I am trying to restore scroll event or scrollbar position after page refresh/reload. Here is my code, but I can't make it work. Tried it on JSFiddle but no luck. Please help! JavaScript code below.
Note: I have a hidden <input> element with an id of scrolled, and a <textarea> with an id of textAreaInput.
function saveScroll()
{
some code
}
function restoreScroll()
{
some code
}
window.onunload = saveScroll;
window.onload = restoreScroll;
So, you don't actually set the #scrolled value when producing the page because its value set in saveScroll never reaches the server. Remember that when a page is reloaded, all the DOM data from the previous load are discarded.
I'd figure that you could try setting this value in a document.cookie but you need to check if this is going to work. Another option is to use window.sessionStorage if one is available in the target environment.
Here is a fiddle for you to play with. Scroll the textarea and refresh the page. You can see the debug output in your firebug or devtools console.
Related
I have a console on my website which shows a log file, and i've set it up so it refreshes every 500 ms.
jQuery(document).bind("ready", function() {
$("#console").animate({ scrollTop: $(document).height() }, 1000);
function doStuff() {
$( "#console" ).load("console/getlog.php");
$('#console').scrollTop($('#console')[0].scrollHeight);
}
setInterval(doStuff, 500);
});
that works fine, but the problem arrives when i try to select some text in the console. Every time it updates, my selection is cancelled
what can i do to solve this?
Instead of using $( "#console" ).load("console/getlog.php"); to update your console, consider using $( "#console" ).append();. This should prevent the whole thing from reloading and removing your selection.
You can do something like append(getLog()); where getLog() is a function that returns the content of the log. Append can be used with hard coded content (text/html) or the results from a function.
More information on .append() here
Also here - jQuery API doc
Like MelanciaUK suggested, pause the doStuff() when the console is in focus.
You may detect that focus via mouseover/mouseout (so the console stops updating when you hover it), or on mousedown/mouseup, which isn't that usable since you have hardly time to press Cmd + C to save your selection.
Some dirty example: http://jsfiddle.net/ZEW5s/ (updated with pause after mouseup: http://jsfiddle.net/ZEW5s/1/)
tymeJV suggestion to use setTimeout instead of setInterval is a good one, though.
The only way i can think of solving it is by making the delay long so you got time to select the text.
Not much of an answer, but I can't comment, so here it goes.
There are some methods for accessing and manipulating the selection, although they depend on the browser if I remember correctly. Check this out:
https://developer.mozilla.org/en-US/docs/Web/API/Selection
I'd recommend changing the doStuff() to save the current selection, and try to apply it after the loading.
I was successful to track all "uiStreamSource" that holds the link associated with each facebook post (status, image, etc) to add one extra button next to the date to do some other tasks using google chrome extensions. This button does a predefined job which not important to mention in this context.
I wrote this content script:
contentscript.js
var nodeslist=document.getElementsByClassName("uiStreamSource");
alert(nodeslist.length);
Each time a facebook page is loaded, the alert shows me 10 detected classes (i.e., 10 posts). But when I scroll down, new posts show up and this code fails to detect them. Since I need to update all uiStreamSource nodes in all posts, how can I solve this?
UPDATE
I tried this code in contentscript.js:
load();
document.addEventListener("DOMNodeInsertedIntoDocument", load, false);
function load(){
var nodeslist=document.getElementsByClassName("uiStreamSource");
alert(nodeslist.length);
}
The first time it runs, I get the correct number of the current nodes (current facebook posts) but once I scroll down and more posts are fetched, the alert shows up indicating that load function is called but the number of nodes printed is 0. Why is that?
Thanks on advance.
You can add a DOMNodeInserted event and check if the element that is going to be inserted is a post by checking its classes.
Or an easy solution is to use the jcade plugin. It can call a callback function when an element with specified selector is inserted.
Listen to the scroll event and add any new posts to nodeslist. You could use setInterval as well to catch any posts that are added when the user is not scrolling.
I'm designing an HTML page which has one button. The user clicks the button and a simple jQuery script animates that div away, revealing lower page content. You can see it here.
I've noticed that it looks/works fine the first time, but if I refresh the page with the browser button, it doesn't fully reset. The initial container is only half on the page. If I enter the URL again and load the page, it resets as expected.
NOTE: This only happens if you scroll down a bit after clicking the initial button... which seems weird.
I had no idea that there was any difference between these two operations, but there clearly is. What is the difference and how can I fix this problem from happening?
Here's my jQuery code, in case it's relevant:
$(document).ready(function(){
var faqs = $("#FAQ");
$("#learnmore").click(
function(){
$("#home").animate({top:'-=1066px'},600);
$("#more").animate({top:'-=1066px'}, 600, function() {$("#background").hide();} );
$("body").css('overflow-y', 'scroll');
//$("#home").slideUp();
console.log("jquery loaded");
}
);
});
It happens because it is cached by the browser.
If you styles are regularly modiefied, then as easy fix is to attach a unique id on the end of the reference, like
<link href="style.css?time=168768234928" ..../>
What it does, it makes the browser think it is a new request everytime it loads.
It happens because browser trying to scroll to the same position, what was before page reload. To check it, try press button and don't scroll to bottom of page and then reload page.
Okey, the reason is clear.
Now we need solution. Try this:
#more {display:none}
in your css. And then use
$("#more").show().animate(...
in your $("#learnmore").click() function. I hope this will solve the problem.
I asked How can I make the “Preview Post” button save and preview in the same window? on the Wordpress Stack Exchange, but this may be a better question for Stack Overflow as it is more directly related to coding.
Wordpress has a box that allows you to save, preview, and publish your blog posting:
The "Preview" button is actually a link styled as a button:
<a tabindex="4" id="post-preview" target="wp-preview"
href="/?p=67&preview=true" class="preview button">Preview</a>
My problem is that I can't seem to figure out how to get that link to open in the current window. Notice the target="wp-preview" part. I'm trying to get rid of that part, but I think there may be another function bound to that element because I really can't get it to open in current tab / window, even after unbinding it and removing the target attribute.
I'm running the following code as part of a plugin (you can see more info on how to run this as a plugin below), but it is also possible to copy and paste this into Chrome or Firefox's console to test this out yourself without even modifying Wordpress. Please note that when testing you'll need to use jQuery instead of $ in your own functions as Wordpress uses the noconflict method, however the code below is working fine as is.
//select the node and cache the selection into a variable
var $node = jQuery('a.preview');
//add a 1px dotted outline to show we have the right element
$node.css('outline','1px dotted red');
//show current target
console.log($node.prop('target'));
//show if anything is bound - nothing is for me ('undefined')
console.log($node.data('events'));
//remove anything bound to it
$node.unbind();
//set target to _self (current window), just in case
$node.prop('target','_self');
//the remove the target attribute all together
$node.removeAttr('target');
//clone the node
var $clone = $node.clone();
//change the text to new
$clone.text('new');
//remove target from clone
$clone.removeAttr('target');
//unbind the clone
$clone.unbind();
//insert the clone after the original node
$node.after($clone);
//show current target - now shows undefined for me
console.log($node.prop('target'));
//show if anything is bound - still 'undefined'
console.log($node.data('events'));
This is how you would work the code into a theme or plugin:
// set up an action to set a function to run in the wp admin_footer
add_action('admin_footer','my_admin_footer_script',9999);
Here is the function that adds the javascript:
//this function can then be used to add javascript code to the footer
function my_admin_footer_script(){ ?>
<script type="text/javascript">
jQuery(function($){
(above js code here)
});
</script>
<?php
}
This is the result I end up with. If I click the "test" link it will open in the same window. If I click the Preview link it still opens in a new tab.
ps: I'm using the method from Things you may not know about jQuery to check for bound events, and I didn't find anything bound, and I believe Wordpress primarily uses jQuery so I don't think this would be bound with another event handler.
You could try this:
jQuery('.preview.button').click(function(e){
window.location.href = this.href;
return false;
});
Works from the Chrome Inspector.
The syntax is right but the timing is important. If you just do the first part but not the second part it is possible that this will not work because it seems there is a delay with the event that binds to this element.
If you include the second part as well, that waits for 500ms after the page is loaded to run, it seems that it works as expected.
add_action('admin_footer','preview_same_window');
function preview_same_window(){ ?>
<script type="text/javascript">
jQuery(function($){
//first part
jQuery('.preview.button').unbind().removeAttr('target');
//second part
setTimeout(function(){
jQuery('.preview.button').unbind().removeAttr('target');
},500);
});
</script>
<?php
}
I have various links which all have unique id's that are "pseudo-anchors." I want them to affect the url hash value and the click magic is all handled by some mootools code. However, when I click on the links they scroll to themselves (or to the top in one case). I don't want to scroll anywhere, but also need my javascript to execute and to have the hash value in the url update.
Simulated sample code:
button 1
button 2
Home
So if you were to click on the "button 1" link, the url could be http://example.com/foo.php#button1
Does anyone have any ideas for this? Simply having some javascript return void kills the scrolling but also kills my javascript (though I could probably work around that with an onclick) but more importantly, prevents the hash value in the url to change.
The whole point of an anchor link is to scroll a page to a particular point. So if you don't want that to happen, you need to attach an onclick handler and return false. Even just adding it as an attribute should work:
button 1
A side of effect of the above is that the URL itself won't change, since returning false will cancel the event. So since you want the URL to actually change, you can set the window.location.hash variable to the value that you want (that is the only property of the URL that you can change without the browser forcing a reload). You can probably attach an event handler and call something like window.location.hash = this.id though I'm not sure how mootools handles events.
(Also you need all of the IDs to be unique)
You can use the code below to avoid scrolling:
linktxt
I'm probably missing something, but why not just give them different IDs?
button 1
button 2
Home
Or whatever convention you'd prefer.
Also, preventDefault
$(your-selector).click(function (event) {
event.preventDefault();
//rest of your code here
}
I found the solution. Here I save an old location from calling href
and restore it after scrolling
<script language="JavaScript" type="text/javascript">
<!--
function keepLocation(oldOffset) {
if (window.pageYOffset!= null){
st=oldOffset;
}
if (document.body.scrollWidth!= null){
st=oldOffset;
}
setTimeout('window.scrollTo(0,st)',10);
}
//-->
</script>
and in body of page
<a href="#tab1" onclick="keepLocation(window.pageYOffset);" >Item</a>
Thanks to sitepoint
An easier way would probably be to add it as a GET. That is, http://example.com/foo.php?q=#button1 instead of http://example.com/foo.php#button1
This won't have any effect on how the page is displayed (unless you want it to), and most scripting languages already have tools in place to easily (and safely) read the data.
Well here we are 7 years after this answer was published and I found a different way to make it work: just point the window.location.hash to a non-existent anchor! It doesn't work for <a>s but works perfectly in <div>s.
<div onclick="window.location.hash = '#NonExistentAnchor';">button 1</div>
Worked fine in Chrome 56, Firefox 52 and Edge (IE?) 38. Another good point is that this doesn't produce any console errors or warnings.
Hope it helps somebody besides me.
There is a solution without any JavaScript at all:
I will not jump to the top
Use
button 1
where
function setHash(hash) {
event.preventDefault();
history.pushState(null, null, "#"+hash);
}
event.preventDefault() stops browser from what it normally would do on clicking, and history.pushState adds to the sessions history stack.
For further discussion, see here and here