I am having an issue getting the height of an object. Please excuse the mass (and mess!) of code it was easier to show the issue this way.
To recreate problem - hit the blue 'play' button - then click the green 'back to where we were' button.
You will see that it doesn't work on the return and I am completely stuck.
To make matters worse I am calculating the height on an element that is visibility: hidden - so I can't even tell if it is collapsing in some weird way!
The problem lies in the atrocity that is my 'getheight()' function but I can't see where it is causing the issue. (code here for reference - the fiddle tells the full story.)
please help me out guys - and do'nt criticise my 'code as I think mess' too much :-D
p.s. - as this is turning into a rather complex and messy lot of code and alternative ways to achieve what I am trying to achieve (morph one container to another without having to absolutely position either of the items) would be appreciated - just some ideas dont want code writing for me!
Fiddle illustrating problem
function getHeight(elem){
var parent = $(elem).parent();
if(parent.css('display') == "none"){
console.log('parent');
parent.css('display', 'hidden');
parent.css('position', 'absolute');
parent.css('display', 'block');
theHeight = $( elem ).height();
parent.css('display', 'none');
return theHeight;
}else{
console.log('element');
var beforePos = $(elem).css("position");
var beforeDisplay = $(elem).css("display");
var beforeVisibility = $(elem).css("visibility");
$(elem).css('visibility', 'hidden');
$(elem).css('position', 'absolute');
$(elem).css("cssText", "display: block !important");
console.log("DISPLAY" + $(elem).css('display'));
theHeight = $(elem).height();
console.log(theHeight);
console.log(beforeVisibility);
console.log(beforeDisplay);
console.log(beforePos);
console.log(elem);
$(elem).css("cssText", "");
$(elem).css('visibility', 'visible');
$(elem).css('display', beforeDisplay);
$(elem).css('position', beforePos);
return theHeight;
}
}
as for getting height of hidden element, jQuery page says this:
The value reported by .height() is not guaranteed to be accurate when the element or its parent is hidden. To get an accurate value, ensure the element is visible before using .height(). jQuery will attempt to temporarily show and then re-hide an element in order to measure its dimensions, but this is unreliable and (even when accurate) can significantly impact page performance. This show-and-rehide measurement feature may be removed in a future version of jQuery.
link to the jQuery height function
Thanks to Mark for pointing me to the documentation - the fix was actually quite simple once I knew what inconsistency jQuery has -
changed:-
theHeight = $(elem).height();
to
theHeight = $(elem).css("height");
and it functions as it should!
now working fiddle
Related
I have a pdf file within iframe. I want user to scroll must in pdf file before submitting the form. i am trying with this,
var position = $('#myIframe').contents().scrollTop();
But not working. Please help me Thanks in advance.
If you don't mind making a static height for your iframe, I have a solution for you.
HTML and CSS
1. Wrap your iframe in a div container
2. set heights for both your container and iframe (height of container should be the height you want your frame to be seen and the iframe height should be large enough to show entire pdf.)
3. set container div's overflow to scroll
Now you have a scrollable "iframe".
Javscript
Get container element. (var containerEl = $("#container")[0];)
Write a scroll function. Within the scroll function find if the total height of the element (scrollHeight) is less than or equal to how much has been scrolled (scrollTop) plus the inner height (clientHeight) of the
element. If it is, remove disabled property from button
Here's the fiddle. Made some changes to #mJunaidSalaat's jsfiddle.
Well I've tried almost an hour on this, Researched it, finally coming to a conclusion that Unfortunately this is not possible using this method.
The PDF is usually not a DOM element, it's rendered by PDF reader software. Every browser has its own mechanism for rendering PDFs, there is no standard. In some cases, the PDF might be rendered by PDF.js; in those situations you might be able to detect scrolling. But Adobe Reader, Foxit, and some of the native PDF rendering don't provide that option.
I've also created a Github issue for this. But no use.
Sorry. Please update me if you could find any thing or any workaround.
I've made a Fiddle for your solution. You can disable the submit button for user until user scroll on your iframe.
function getFrameTargetElement(objI) {
var objFrame = objI.contentWindow;
if (window.pageYOffset == undefined) {
objFrame = (objFrame.document.documentElement) ? objFrame.document.documentElement : objFrame = document.body;
}
return objFrame;
}
$("#myIframe").ready(function() {
var frame = getFrameTargetElement(document.getElementById("myIframe"));
frame.onscroll = function(e) {
$('.submitBtn').prop('disabled', false);
}
});
Hope it helps.
try this
$("#myIframe").ready(function() {
var frame = getFrameTargetElement(document.getElementById("myIframe"));
frame.onscroll = function(e) {
$('.submitBtn').prop('disabled', false);
}
});
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.
So I haven't yet started writing any of this, so I'll do my best to put together some pseudocode for the sake of clarity - but the idea here is that a user would click and hold on a 'button' ( might not end up being an actual button ), that then spawns a movable DIV. Once the DIV has been created ( wherever the mouse is at the time, perhaps offset a little so the mouse is inside the div ), I'd like to switch my 'hold focus' to the new, movable DIV, so that it can be positioned on the screen; at which time I'll do some other operations on the DIV - but after this point the remainder is irrelevant to the question.
In true, incomplete pseudocode - this is roughly what I'm after; and I believe that my biggest question here is how to actually change my grab focus.
<script>
function NewDiv()
{
NewDiv = CreateDiv(MouseX, MouseY);
GrabDiv(NewDiv);
}
function CreateDiv(X, Y)
{
// DOM for a new DIV... I've got this part covered...
// JQuery for Movable - Covered
NewDiv.style.left=(X - 3) + "px";
NewDiv.style.top=(Y - 3) + "px";
return NewDiv;
}
function GrabDiv(Div)
{
// Here's the question...
// Div.Focus? - While the mouse is still down, I might think this would work?
// Div.onMouseDown? - Buuuuuut... Is that going to interact with the mouse properly?
}
</script>
<input type='button' onMouseDown='NewDiv();' value="Spawn a new Div" />
Now - again, the real question is what the 'proper' approach to the 'GrabDiv' function would be. Any feedback is much appreciated; and if I need to elaborate at all I'm glad to.
-- It looks like there may have been at least one other post on something like this; with a pretty convoluted answer. Perhaps this little bump will encourage a new answer. Hopes.
Have you seen this working somewhere else?
I would look into using jQuery-UI's drag and drop.
Edit: I guess it does work. I would use this jsbin as a starting point: http://jsbin.com/deyovunaxe/2/edit
This question already has answers here:
Is there a way to force a user to scroll to the bottom of a div?
(6 answers)
Closed 8 years ago.
I can't find a website at the moment, because I'm not at my desk where this is done, but I have seen it when you register there is a Terms of Use. To make sure the user reads it, it appears in a dialogue box (not sure of the exact name of this in HTML) and the "register" button stays greyed out until the user scrolls through the entire Terms of Use. How is this done? I am assuming this is JavaScript, but I don't know how to detect and control this. Some examples of this or how this is done in JavaScript would be very helpful. Thanks!
You can do this without jQuery with the following code:
//Your DIV with the TOS
var i=document.getElementById("ipsum");
//Event Listener for Scroll
i.onscroll=function(){
//Your Button
var y = document.getElementById("yay");
//The height to scroll to:
var x = i.scrollHeight - i.offsetHeight - 1;
if(i.scrollTop >= x)
y.removeAttribute("disabled");
else if(!y.hasAttribute("disabled"))
y.setAttribute("disabled",true);
};
Fiddle with HTML and CSS here.
Also, I agree with everyone else who's posted or commented, this is probably not a good idea.
You want to check the scrollTop is toward the bottom of the scrollHeight on the element.
$('.tos').scroll(function() {
if ($(this).scrollTop() + $(this).height() >= $(this)[0].scrollHeight - 100) {
$('input[type="submit"]').prop('disabled', false);
}
});
Adapted from this answer
Here is a jsfiddle example.
Warning: Before you implement this
This will not detect if the user has read the terms. It is also extremely annoying to have to scroll through these (often tiny) TOS boxes.
A much, much better solution is to require the user to explicitly tick a box stating they have read and understand the TOS.
The best way to understand this is to look at this fiddle.
Notice how mouse wheel over the fixed content in the red box does nothing. I would like the scrollable div to scroll.
In case the fiddle dies - basically I have a scrollable div with a fixed element over it. Typically when you mouse wheel over a scrollable div it will of course scroll. But if you are over the fixed element instead then no scroll happens. Depending on your site layout this could be counter intuitive to a user.
jQuery solutions are okay.
A much, MUCH simpler, but much less widely supported, answer is the following:
#fixed{ pointer-events:none; }
jsFiddle
Doesn't work in IE at all though unfortunately! But you could use modernizr or somesuch to detect whether it was supported and use the jQuery as a stop-gap where it isn't.
Courtesy of Mr. Dominic Stubbs
I had this problem and this works for me (using jquery):
$(document).ready( function (){
$('#fixed').on('mousewheel',function(event) {
var scroll = $('#container').scrollTop();
$('#container').scrollTop(scroll - event.originalEvent.wheelDeltaY);
return true;
});
});
Works on Safari and Chrome: http://jsfiddle.net/5bwWe/36/
I think this does what you're asking for!
$('#fixed').bind('mousewheel', function(e){
var scrollTo= (e.wheelDelta*-1) + $('#container').scrollTop();
$("#container").scrollTop(scrollTo);
});
EDIT: Updated the jsFiddle link to one that actually works
DOUBLE EDIT: Best to dispense with the .animate() on further testing...
jsFiddle Example
TRIPLE EDIT:
Much less pretty (and will probably be horribly slow with a lot of elements on the page), but this works and I owe a lot to this stackoverflow answer.
$('#fixed').bind('mousewheel', function(e) {
var potentialScrollElements = findIntersectors($('#fixed'), $('*:not(#fixed,body,html)'));
$.each(potentialScrollElements, function(index, Element) {
var hasVerticalScrollbar = $(Element)[0].scrollHeight > $(Element)[0].clientHeight;
if (hasVerticalScrollbar) {
var scrollTo = (e.wheelDelta * -1) + $(Element).scrollTop();
$(Element).scrollTop(scrollTo);
}
});
});
function findIntersectors(targetSelector, intersectorsSelector) {
var intersectors = [];
var $target = $(targetSelector);
var tAxis = $target.offset();
var t_x = [tAxis.left, tAxis.left + $target.outerWidth()];
var t_y = [tAxis.top, tAxis.top + $target.outerHeight()];
$(intersectorsSelector).each(function() {
var $this = $(this);
var thisPos = $this.offset();
var i_x = [thisPos.left, thisPos.left + $this.outerWidth()]
var i_y = [thisPos.top, thisPos.top + $this.outerHeight()];
if (t_x[0] < i_x[1] && t_x[1] > i_x[0] && t_y[0] < i_y[1] && t_y[1] > i_y[0]) {
intersectors.push($this);
}
});
return intersectors;
}
UPDATE (August 2016): It seems the browser implementations have changed and it's no longer possible to re-dispatch a WheelEvent on a different target. See the discussion here.
For an alternative solution that should work across platforms, try this:
var target = $('#container').get(0);
$('#fixed').on('wheel', function (e) {
var o = e.originalEvent;
target.scrollTop += o.deltaY;
target.scrollLeft += o.deltaX;
});
Working example: https://gist.run/?id=6a8830cb3b0564e7b16a4f31a9405386
Original answer below:
Actually, the best way to do it is to copy the original event. I've tried #Tuokakouan's code but scrolling behaves strangely (too fast) when we use a multitouch touchpad that has inertia.
Here's my code:
var target = $('#container').get(0);
$('#fixed').on('wheel', function(e){
var newEvent = new WheelEvent(e.originalEvent.type, e.originalEvent);
target.dispatchEvent(newEvent);
});
You can try it here: http://jsfiddle.net/NIXin/t2expL6u/1/
What I'm trying to do now is also to pass the touch events, without much success. Since mobile phones and touch screens are now more popular, some people might want to scroll using their fingers instead - neither of the answers offered solves that.
Well,all solutions with js are kind of delayed when scrolling on it. if the fixed element you use is just for display, then I have a good css tricks to achieve that.
make the fixed element z-index:-1 and the container element background-color:transparent
here is the jsfiddle you can see: https://jsfiddle.net/LeeConan/4xz0vcgf/1/