I have a page containing a push button and two radio buttons placed near the bottom of the page. My goal is to create a function triggered by the push button that scrolls the page up or down, depending on whether or not the two radio buttons are active. Once users select the two radio buttons, the push button will then scroll to the top of the page. The snippet provided has the code that I have so far. Once the two radio buttons are activated, I want the 'scroll down' code to no longer work and just have the button move the user to the top of the page. It works as intended in this example and in Firefox, but chrome and edge have trouble interpreting it. In these browsers, the page will scroll to the bottom when it is at the top, which makes sense considering that the 'scroll-down' code is placed at the beginning of the function. How can the code be optimized/separated so that it works as intended without the two window.scrollTo's interacting with each other?
function Push() {
window.scrollTo(0,document.body.scrollHeight);
if(mode1.checked) {
if(mode2.checked) {
window.scrollTo({top: 0});
}}}
<style>
html {
height: 500px;
}
</style>
<body>
</br></br></br></br></br></br></br></br></br></br></br>
<div align="center">
<button id="button01" onclick="Push()">Push</button>
</div>
</br></br></br></br></br></br></br></br></br></br></br></br>
<div align="center">
<form id="mode">
<label><input type="radio" id="mode1"/></label>
<label><input type="radio" id="mode2"/></label>
</form>
</div>
</body>
The way you have it written; when both radios are checked and the Push() function is called, the page will scroll to the bottom first and then to the top. It happens so fast you don't notice it (at least I don't), but the code says that is happening.
EDIT: I did prove that this is the case by testing in codepen by setting a breakpoint here: window.scrollTo({top: 0});. When it breaks here it has scrolled to the bottom and then when I step into the next function call it scrolls to the top.
I would change the Push() function like this:
function Push() {
if(mode1.checked && mode2.checked) {
window.scrollTo({top: 0});
} else {
window.scrollTo(0,document.body.scrollHeight);
}
}
Doing so results in only one scroll action firing (up or down).
It also appears that IE does not support using scrollTo with options as you do here: window.scrollTo({top: 0});. May be best to use window.scrollTo(0,0). I used that in the snippet below.
This may be your Chrome and Edge issue as well depending on what version of each you are testing on. See this: https://caniuse.com/#feat=element-scroll-methods
One last notable observation: You currently have no way to "uncheck" the radio buttons due to the designed functionality of radio buttons. I assume you know that and is not an issue, but thought I would mention it. Using checkboxes or custom checkboxes would allow you to accomplish this if needed. There are other ways to accomplish this as well.
function Push() {
if(mode1.checked && mode2.checked) {
window.scrollTo(0,0);
} else {
window.scrollTo(0,document.body.scrollHeight);
}
}
html {
height: 500px;
}
<html>
<body>
</br></br></br></br></br></br></br></br></br></br></br>
<div align="center">
<button id="button01" onclick="Push()">Push</button>
</div>
</br></br></br></br></br></br></br></br></br></br></br></br>
<div align="center">
<form id="mode">
<label><input type="radio" id="mode1"/></label>
<label><input type="radio" id="mode2"/></label>
</form>
</div>
</body>
</html>
Related
My issue involves multiple DIVs that display:block or display:none each with their own anchor tag. The main problem is that I have recommissioned the JS code that runs this feature without completely understanding it. All I need is a way to toggle all of the DIVs with a single "Show All/Hide All" link. I cannot wrap my head around it.
I have tried absolutely everything that my exceptionally limited grasp will allow - which consists mostly of swinging my arms in the dark and hoping I accidently build a miracle. Since that hasn't worked I am shamefully seeking help.
The only thing that makes this question unique are all the variables with this specific issue -
An (almost) working example can be found at: www.robertmeans.com/menu.htm
The JS code:
imageX01='plus';
imageX02='plusEven';
function toggleOdd(ee){
imgX="imagePM"+ee;
divX="div"+ee;
imageX="imageX"+ee;
divLink="divHref"+ee;
imageXval=eval("imageX"+ee);
element = document.getElementById(divX).style;
if (element.display=='none') {element.display='block';}
else {element.display='none';}
if (imageXval=='plus') {document.getElementById(imgX).src='_images/minus.gif';eval("imageX"+ee+"='minus';");document.getElementById(divLink).title='Hide Content';}
else {document.getElementById(imgX).src='_images/plus.gif';eval("imageX"+ee+"='plus';");document.getElementById(divLink).title='Show Content';}
}
function toggleEven(ee){
imgX="imagePM"+ee;
divX="div"+ee;
imageX="imageX"+ee;
divLink="divHref"+ee;
imageXval=eval("imageX"+ee);
element = document.getElementById(divX).style;
if (element.display=='none') {element.display='block';}
else {element.display='none';}
if (imageXval=='plusEven') {document.getElementById(imgX).src='_images/minusEven.gif';eval("imageX"+ee+"='minusEven';");document.getElementById(divLink).title='Hide Content';}
else {document.getElementById(imgX).src='_images/plusEven.gif';eval("imageX"+ee+"='plusEven';");document.getElementById(divLink).title='Show Content';}
}
The HTML
<div id="task_item01">
<img src="_images/plus.gif" alt="" name="imagePM01" width="33" height="33" border="0" class="task_itemPlusImage" id="imagePM01" />
Div #1
</div>
<div style="display:none;" id="div01">
Content 1
</div>
<!-- ******************************** Item 1 End **************************** -->
<!-- ******************************** Item 2 Start ************************** -->
<div id="task_item02">
<img src="_images/plusEven.gif" alt="" name="imagePM01" width="33" height="33" border="0" class="task_itemPlusImage" id="imagePM02" />
Div #2
</div>
<div style="display:none;" id="div02">
Content 2
</div>
I have spent countless hours trying to work this out on my own. Any help is deeply appreciated.
Ok first of all, it seems like way too much code to me... you can do this very easily by using jQuery. I have made an example here: http://jsfiddle.net/Nr2f6/4/
Here is some simple html to help you better understand what is being done:
<div id="item-1"><span class="plus"></span>Open these items</div>
<div class="contents" data-rel="item-1">
I have superb items in this div... the world is about to understand just how awesome I am!
</div>
<div id="item-2"><span class="plus"></span>Open these other items</div>
<div class="contents" data-rel="item-2">
I have amazing contents in this div. I want to show them to the world!
</div>
as you can see above, there is no inline css. All the styling (display: none) should be placed separately, to not conflict with what you are trying to do. So simply place it in a separate css file.Then run this code:
$("div[id^=item]").click(function(){
var reference2open = $(this).attr("id");
//get the data-rel attribute associated
$("div[data-rel='"+reference2open+"']").slideToggle();
$("span",this).toggleClass('minus');
});
$("#all").click(function(){
if($(this).hasClass('close')){
$("div[data-rel^=item]").slideUp();
$("div[id^=item] span").removeClass('minus');
$("#all").removeClass('close');
$("#all").html('open them all');
}else{
//open and close them all by clicking
$("div[data-rel^=item]").each(function(){
if($(this).is(':hidden')){
$(this).slideDown();
$("div[id^=item] span").addClass('minus');
$("#all").html('close them all');
}
});
//change the button to close
$("#all").addClass('close');
}
//$("div[id^=item] span").toggleClass('minus');
});
****ADDED IN THE TOGGLE PLUS AND MINUS SIGNS USING CSS****
.plus{
background: url(http://www.robertmeans.com/offsite_files/code_help/_images/plus.gif);
width: 33px;
height: 33px;
display: inline-block;
}
.minus{
background: url(http://www.robertmeans.com/offsite_files/code_help/_images/minus.gif);
width: 33px;
height: 33px;
display: inline-block;
}
Do not forget to include your jQuery file! Hope this helps :)
Just wanted to add in some details for better understanding:
div[id^=item]: Is saying whenever a div is clicked that has an id that starts with (^=) item, run the code.
$("div[data-rel='"+reference2open+"']").slideToggle(): is saying take the id from the div that was clicked and find the content box where with the same name but in the data-rel attribute. The slide it down, if it is already down, slide it back up (toggle). You do not have to use a slide effect, I just thought it was more fun!
Then last but not least, the function you were looking for: How to open them all at once. Again we are using the (^=) to find all of the divs.
$("div[data-rel^=item").slideToggle();: So here we are saying to jQuery, hey toggle all the boxes that have a data-rel attribute that starts with (^=) item.
This last part is pretty neat, because you can create many instances of the item-? boxes and this code will work for any number of them. You can also add the same code to a different div, like even and odd, and toggle all the even and all the odd elements accordingly.
You could assign a specific class to all the things you want to toggle, then loop through all of them with a toggle function.
So I have some working JS code on my site which swaps on div to another div once the link has been clicked. However I currently have it work on top of an iframe by overlaying a clear gif which is the link and it works perfectly.
Now I want to apply it to a button which is pressed on our site to create a download - I can't use the same invisible gif trick as the button has a mouse over effect which then doesn't work so I want it to happen some other way when clicking on the button. The function which currently works is loaded in the header as…
function yourFunction(){
document.getElementById('yourfirDiv').style.display='block';
document.getElementById('yoursecDiv').style.display='none';
}
At the moment the link which triggers this is an image which works perfectly and looks as follows…
<a href="javascript:void(0)" onclick="var fileref=document.createElement('script');fileref.setAttribute('type','text/javascript'); fileref.setAttribute('src', 'http://url.com/locker.js?guid=0512eafd69b18d22');document.body.appendChild(fileref); setTimeout(yourFunction, 3000);">
<img src="http://url.com/blank.gif" style="position: absolute; z-index: 500; width: 100%; max-width: 100%; height: 280px; ">
</a>
Now I need to apply this to do the same thing on this button…
<div id="yoursecDiv" style="display:block;">
<div id="downloadmp3">
<div class="download_button_div">
<form action="/download_file.php" method="post" name="downloadform">
<input name="file_name" value="<?php echo $fname; ?>" type="hidden">
<input name="bucket" value="<?php echo $bucket; ?>" type="hidden">
<button type='submit' class='download_button' title="Click to Download Mixtape!">Download</button>
</form>
</div>
</div>
</div>
Someone gave me some simple JS which is as follows which should trigger when a div name is clicked to trigger the function which swaps the named divs, however it doesn't work, the code snippet is…
$("#clickablediv").bind("click",function(){
yourFunction();
});
To make things slightly more complicated, the page is a floating page launched with ajax, so any code like the above has to go in the sites JS file in the part which loads the page if it needs to be loaded on launch of a portfolio. In the case of the link above the function code loads in the global site header just fine and the inline JS works fine - perhaps there is a way to apply that link to my button divs somehow, simple inputs very welcome!
I think isherwood is correct in that you're overcomplicating things.
However, try this:
$(document).ready(function() {
$(document).on("click","#clickablediv",function(){
$('#yourfirDiv').show();
$('#yoursecDiv').hide();
});
});
Assuming #yourfirDiv has either style or class css with "display:none".
Then you can remove those pesky onclick attributes from the divs.
I am using a checkbox and a checkbox list in one of my web pages.
The UI is like
Color - Header Checkbox
Checkboxlist items are
Red
Green
Blue
Yellow
Complete selection - clicking on the header checkbox selects/ deselects the entire checkbox list.
Partial selection of the checkbox list shows the header checkbox with a different background color to indicate partial selection.
I do a check for number of selected items in each of the checkbox list selection changes. In a client server environment, there is a time delay and if we make two continuous selections in the checkbox list, an update of the header control is done for the first selection and by the time UI is refreshed, the second selection is gone.
I also implemented the above one using JavaScript but then also the behavior is same.
What could be an alternative for this?
Your question is not particularly clear, but it sounds like you want some sort of three state check box? It also sounds like the postback is occurring and wiping out your second selection?
If so, there are some control options out there. Here's a link to one that may help. http://www.chadscharf.com/index.php/2008/10/3-state-checkbox-using-microsoft-ajax/
You really need to post some code and link to the screen shots you mention.
There are two scenarios you are trying to satisfy and the simpliest approach is utilising Javascript. Certainly one direction is using Jquery to simplify the wiring of DOM elements together.
Following is an example that kinda covers the two scenarios. One the top level control checks / unchecks all the elements. Second, the individuals change the background of the top level element. This is not drop and run code, it merely demonstrates the technique in isolation. Changes and tweaks I've leave to you + if you're unfamiliar with Jquery: simply search each function on Jquery site. Enjoy!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
// Wire up the 'select-all' to the child elements
$('#topLevel').bind('change' , function(){
// Record this object
var base = this;
// Change the child elements
$('#checkboxContainer input').each( function(){
$(this).attr('checked' , $(base).is(':checked'))
})
});
// Make the individual checkbox selects alter the
// background of the top-level wrapper
$('#checkboxContainer input').bind('change' , function(){
// Get a handle to the top item
var topLevel = $('#topLevelWrapper');
// Have we selected the item?
if($(this).is(':checked')){
// Remove the previous class assignments
topLevel.attr('class' , '');
// Assign the current css class from the parent
topLevel.addClass( $(this).parent().attr('class') );
}
});
})
</script>
<style type="text/css">
.Red{
background-color:#F00;
}
.Green{
background-color:#0F0;
}
.Blue{
background-color:#00F;
}
</style>
</head>
<body>
<div id="topLevelWrapper">
<label for="topLevel">Top level selection</label>
<input type="checkbox" id="topLevel" />
</div>
<div id="checkboxContainer">
<ul>
<li class="Red">
<label for="topLevel">Red</label>
<input type="checkbox" />
</li>
<li class="Blue">
<label for="topLevel">Blue</label>
<input type="checkbox" />
</li>
<li class="Green">
<label for="topLevel">Green</label>
<input type="checkbox" />
</li>
</ul>
</div>
</body>
First of all, what my script does is allow me to swap divs by using a checkbox.
JS Fiddle Example: http://jsfiddle.net/yHTFF/8/
I'm seeking help with setting up cookies properly for this script. I'd like to set this up so that the div and checkbox the user leaves it at remains the same upon page reload.
Here's my script:
<!--HTML-->
<div id="ontopic_posts">
Content 1
</div>
<div id="offtopic_posts" style="display: none;">
Content 2
</div>
<input id="cbox_posts" type="checkbox"> show off-topics
<!--JQUERY-->
<script>
jQuery("#cbox_posts").click(function() {
if ( jQuery(this).is(':checked') )
{
jQuery("#offtopic_posts").show();
jQuery("#ontopic_posts").hide();
}
else
{
jQuery("#offtopic_posts").hide();
jQuery("#ontopic_posts").show();
}
});
</script>
Thanks!
You attach the event handler before the element exists.
Move the script tag after the input or wrap the script with $(document).ready.
can anyone help me out, been banging my head against a wall for 2 days! Trying to get iScroll to work with my phonegap/jqtouch app. Have tried all the suggestions I can find on the Internet, but all I get is either no scrolling or rubber banding so I can't view the bottom of the page.
My code in a nutshell is:
HTML header:
<script type="text/javascript" charset="utf-8" src="phonegap.js"></script>
<script type="text/javascript" src="jqtouch/jquery.js"></script>
<script type="text/javascript" src="jqtouch/jqtouch.js"></script>
<script type="text/javascript" src="iscroll-lite.js"></script>
<script type="text/javascript" src="myAppCode.js"></script>
<script type="text/javascript">
var myScroll;
function onBodyLoad()
{
document.addEventListener("deviceready",onDeviceReady,false);
}
function onDeviceReady()
{
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
document.addEventListener('DOMContentLoaded', loaded, false);
}
function loaded()
{
myScroll = new iScroll('wrapper');
myScroll.refresh();
}
</script>
HTML (I've added the 'wrapper' and 'scroller' divs):
<!-- Options Page header bar-->
<div id="options_page">
<div class="toolbar">
<h1>Past Paper</h1>
<a class="button flip" href="#reset_page">Reset Stats</a>
</div>
<!-- why won't you scroll??? -->
<div id="wrapper">
<div id="scroller">
<!-- Stats section div - dynamically generated stats by refreshStats() -->
<div id="Stats"></div>
<h2>General</h2>
<ul class="rounded">
<li>Only new questions?<span class="toggle"><input type="checkbox" id="notSeen" /></span></li></ul>
<h2>Categories</h2>
<ul class="rounded">
<li>Cardiology<span class="toggle"><input type="checkbox" id="cardiology" /></span></li>
<li>Respiratory<span class="toggle"><input type="checkbox" id="respiratory" /></span></li>
<li>Gastrointestinal<span class="toggle"><input type="checkbox" id="gastrointestinal" /></span></li>
<li>Neurology<span class="toggle"><input type="checkbox" id="neurology" /></span></li>
</ul>
<div id="optionStartQuiz">
<ul><li class="whiteButton">Start!</li></ul>
</div>
</div>
</div>
</div>
myAppCode.js contains the refreshStats() function to display info in the Stats div above:
$(document).ready(function()
{
// load variables from local storage
loadLocalStorage();
// load the stats div
refreshStats();
// refresh scores everytime the main page is loaded
$('#main_page1').bind('pageAnimationStart', function(){
refreshStats();
});
});
function refreshStats()
{
// an HTML ul
var tempStats = '<h2>Current Stats</h2><ul class="rounded"><li>Questions completed<span style="float: right">' + OVERALL_questionsFirstTime + '/' + OVERALL_numberOfQuestions + '</span></li><li>Percentage correct<span style="float: right">' + percentageScore + '%</span></li></ul>';
// display me
$('#Stats').html(tempStats);
}
So basically I want to be able to scroll the stuff within the wrapper and scroller divs but can't get my head around it! Thanks, Nick
I was having the same problem. The div that was supposed to scroll would exhibit rubberbanding until I changed the orientation on the iphone. I tried the timeout methods from the iscroll doc page but nothing worked.
Using v4.0 beta4 I added
checkDOMChange: true
when creating my scroll wrapper. This works like a charm. Not really sure what the problem was but I am using this in a jQTouch page.
One thing to note, the checkDOMChange: is listed as being experimental...
hth
Ok finally got this working. To get jQTOuch and iScroll to play nice with each other, the scrolling areas on the page need to be reset each time JQTouch makes them disappear. In other words, once you hide the div, iScroll doesn't know what to scroll the next time it's made visible. So as a result, you get the infamous rubberband effect. To solve this, just add an event listener that resets the scrolling area right after the div is called. Make sure you give it 100 to 300ms delay. This code below assumes your variable is called myScroll:
$(".about").tap(function(){
setTimeout(function(){myScroll.refresh()},300);
});
And on a side note, here's how to establish multiple scrollers using iScroll:
var scroll1, scroll2;
function loaded() {
scroll1 = new iScroll('wrapper1');
scroll2 = new iScroll('wrapper2');
}
Hope this helps someone.
I was facing the same issue. My element used just to bounce and settle back.
I edited the scroll.js to make checkDOMChanges:true and it started working fine.
This is my solution.
$("a").tap(function(){
setTimeout(function(){myScroll.refresh()},300);
});
The codes above assume that your iScroll variable is myScroll,
and the code is force your iScroll to refresh as you tap a link.
I'm not sure about iScroll4, but the original iScroll depended on CSS classes to scroll correctly - specifically, the wrapper needed to be positioned, and have overflow set - in the demo for iScroll4 I see they are still setting similar properties on the wrapper and the scroller:
http://www.cubiq.org/dropbox/iscroll4/examples/simple/
I'm not sure if you've already done this (and just didn't include the CSS) - but your code looks fine.
I've had inordinate troubles with iScroll (pre-iScroll4, haven't tested 4 yet) getting it to work with DIVs instead of UL lists. BUT... today I found a post in google groups (see reply by manmade at 9:59) where it is suggested to add a line:
that.refresh();
into the iScroll code around line 81. In the latest iScroll (v3.7.1), this line is added at line 85, within the case for "START_EVENT" just after the line:
that.touchStart(e);
I haven't analyzed exactly why it works, but it works for getting my div to scroll perfectly.