window.location.hash not working? - javascript

I have a link (index.html#services) and a <div id="services> that I'm trying to change the background color of when the link is clicked and then fade back. I'm using the latest jQuery and jQuery Color plugin, and:
$(document).ready(function(){
if(window.location.hash === '#services') {
var service = $('#services');
var originalColor = service.css('background-color');
service.css('background-color', '#FFEE9F').animate({
'background-color': originalColor
}, 3000);
}
});
to do the highlighting, but it's not working. Anyone know why?

That code is only run when the page is loaded, not when a link with a hash is clicked. Try following the link (index.html#services) directly from a new browser tab and it will probably work. What you need to do is run that code when the hash is changed. New browsers have an onhashchange event - but no such thing on older browsers. For old browsers you could poll the hash property every so often to see if it has changed.
If by chance you have a specific identifier (css class, id, name, etc.) on the links that trigger that animation, you could add a click listener to run that code. For example:
function animateBackground() {
var service = $('#services');
var originalColor = service.css('background-color');
service.css('background-color', '#FFEE9F').animate({
'background-color': originalColor
}, 3000);
}
$(function () { // shortcut to $(document.ready)
$('.fade-bg').live('click', animateBackground);
animateBackground();
});

Or use
window.onhashchange = function(){
if(window.location.hash === '#services') {
var service = $('#services');
var originalColor = service.css('background-color');
service.css('background-color', '#FFEE9F').animate({
'background-color': originalColor
}, 3000);
}
};
depending on which browsers you target.

Related

changing the url without loading a new page

For my single page website, I have an index of projects. If a project is clicked it opens up a slideshow on the same page. So basically, I only have one URL, and if anyone wants to link to a specific project, they can't.
I'm trying to make it so that if I click on a project, it changes the URL. And so that URL can be used to get to my website with that project opened.
Here is a link to what I have so far.
For reference, I'm trying to achieve something that is found on this site.
I found some good suggestions here, but what happens when I use something like this (below), a new URL is created but it doesn't open up the project if I renter that URL into the browser.
<a href="#" id='click'>Click to change url to bar.html</a>
<script type="text/javascript">
var stateObj = { foo: "bar" };
function change_my_url()
{
history.pushState(stateObj, "page 2", "bar.html");
}
var link = document.getElementById('click');
link.addEventListener('click', change_my_url, false);
</script>
function processAjaxData(response, urlPath){
document.getElementById("content").innerHTML = response.html;
document.title = response.pageTitle;
window.history.pushState({"html":response.html,"pageTitle":response.pageTitle},"", urlPath);
}
You can use `window.onpopstate to sense the back/forward button navigation
window.onpopstate = function(e){
if(e.state){
document.getElementById("content").innerHTML = e.state.html;
document.title = e.state.pageTitle;
}
};
I would appreciate someone with more skill to check this over for me
You can use id at elements which has slideshow as unique URL; at .ready() start animation of element where id matches .location.hash
$().ready(function() {
// `location.hash`: `id`: `#slideshow1` of element linked to
// from, e.g., `http://example.com/#slideshow1`
var currentSlideshow = $(location.hash);
// do slideshow stuff at `currentSlideshow`: `#slideshow1` element
})
using a hash might work best in this case
$(document).ready(function({
//loading a page
var project = window.location.hash
yourProjectLoadFunction(project);
//setting a url
$('.number').click(function(e){
$this = $(this);
window.location.hash = $this.attr('id');
});
});

Trigger jQuery event on pageload

I have the following jQuery:
// change the number of finished and missing assets
$('.add-requirements .overall-status .status-dropdown li').live('click', function() {
var remaining_titles = $('.item-section.finished').length;
$('.add-requirements .remaining-titles').text(remaining_titles);
});
It fires whenever a status dropdown is changed. How would I also make it fire when the page loads?
From what I can understand you want to update the remaining count on page load and I assume that the finished status is pre setted on the desired elements.
I'll go about this in another way
$('.add-requirements .overall-status .status-dropdown li').live('click', updateRemaining);
updateRemaining()
function updateRemaining(){
var remaining_titles = $('.item-section.finished').length;
$('.add-requirements .remaining-titles').text(remaining_titles);
}
Just chain on a trigger('click') to trigger a click on first pageload :
$('.add-requirements .overall-status .status-dropdown li').live('click', function() {
var remaining_titles = $('.item-section.finished').length;
$('.add-requirements .remaining-titles').text(remaining_titles);
}).trigger('click');
But you should really be using on()
$('closest_non_dynamic_parent').on('click', 'your_freakishly_long_selector', function() {
A bit more verbose, but here is what worked for me:
var remaining_titles_section = $('.add-requirements .remaining-titles');
remaining_titles_section.text($('.item-section.finished').length);
$('.add-requirements .overall-status .status-dropdown li').live('click', function() {
var remaining_titles = $('.item-section.finished').length;
remaining_titles_section.text(remaining_titles);
});

Number, hover (etc) effect not work after Ajax Load More

I'm using Drupal 7 and get my content with View module on page. And my pager Views Load More module. And my thumbnail effect hover, shadow etc. Image hover using this code:
var hoverImg = '<div class="hoverimg"></div>';
$(".thumb").each(function(){
$(this).children("div").each(function(){
$(this).find("a").append(hoverImg);
});
});
$(".thumb div").hover(function() {
$(this).find(".hoverimg").animate({ opacity: 'toggle' });
});
$(".thumb").hover(function() {
$(this).find("div").each(function(){
$(this).find(".shadow").fadeOut(500);
});
});
And getting number on my current thumbnail. This code:
var c = '';
var d = '';
$('.view-content div.views-row').each(function(){
c = 0;
d = 0;
var i = 1;
d = $(this).find('.thumbimg').length;
$(this).find('.thumbimg').each(function(){
sayi=i++;
$(this).append('<div class="img_no">0'+sayi+'</div>');
});
});
Everything is OK. All effects on start page. But when click Load More button, my effects can't work another page.
How do i solve this problem? Thanks.
The reason why it stops working is due to the hover function (and your other scripts/functions) only works on existing elements. So if you add something with ajax, it wont apply to that unless you reload the script after the ajax load.
Another option is to use live() or on() (for the hover part. On is the new version of live, added in jQuery 1.7).
Live and on listens for any existing or future elements.
A live script would look something like this:
$(".yourElement").live({
mouseenter:
function () {
// Do something
},
mouseleave:
function () {
// Do something
},
mousemove:
function () {
// Do something
}
});

How can I use jQuery and Javascript from firefox add-on?

I can't create a new element in the page. I check the page and domain when the page is onload, that's work, but I don't know how can I create a new element in the correct window page.
window.addEventListener("load", function() { myExtension.init(); }, false);
var myExtension = {
init: function() {
var appcontent = document.getElementById("appcontent"); // browser
if(appcontent)
appcontent.addEventListener("DOMContentLoaded", myExtension.onPageLoad, true);
},
onPageLoad: function(aEvent) {
var unsafeWin = aEvent.target.defaultView;
if (unsafeWin.wrappedJSObject) unsafeWin = unsafeWin.wrappedJSObject;
var locationis = new XPCNativeWrapper(unsafeWin, "location").location;
var hostis = locationis.host;
//alert(hostis);
if(hostis=='domain.com')
{
var pathnameis=locationis.pathname;
if(pathnameis=='/index.php')
{
$("#left .box:eq(0)").after('<div id="organic-tabs" class="box"></div>'); // this code somewhy doesn't working, but if I copy to FireBug it't work.
}
}
}
}
My question is: How can I use Javascript and jQuery from firefox addon when I want to manipulate html in the correct window content? What is need from here
$("#left .box:eq(0)").after('<div id="organic-tabs" class="box"></div>');
for working.
This code has a bunch of issues. For one, appcontent is not the browser, gBrowser is. So it should be:
init: function() {
gBrowser.addEventListener("DOMContentLoaded", myExtension.onPageLoad, true);
},
Then, using wrappedJSObject is absolutely unnecessary (and also not safe the way you do it).
var wnd = aEvent.target.defaultView;
var locationis = wnd.location;
Finally, you are trying to select an element in the browser document (the document that your script is running in), not in the document loaded into the tab. You need to give jQuery an explicit context to work on:
$("#left .box:eq(0)", wnd.document)
But you shouldn't use jQuery like that, it defines a number of global variables that might conflict with other extensions. Instead you should call jQuery.noConflict() and create an alias for jQuery within myExtension:
var myExtension = {
$: jQuery.noConflict(true),
....
myExtension.$("#left .box:eq(0)", wnd.document)
Here is a template you can use that incorporates your sample code. I also added an additional statement so you could see another use of jQuery. Important points:
You must load jQuery before you can use it. You should myplace the jQuery library file you want to use in Chrome, for example, in the chrome/content directory.
Use window.content.document as the context for every jQuery
operation on the contents of the Web page
Use this as the context of a successful search result to help you
insert code in the correct spot.
window.addEventListener('load', myExtension.init, false);
var myExtension = {
jq : null,
init : function() {
var app;
// Load jQuery
var loader = Components.classes["#mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader);
loader.loadSubScript("chrome://myExtension/content/jquery-1.5.2.min.js");
myExtension.jq = jQuery.noConflict();
// Launch extension
if ((app = document.getElementById("appcontent"))) {
app.addEventListener("DOMContentLoaded", myExtension.run, true);
}
},
run : function() {
// make sure this is the correct Web page to change
var href = event.originalTarget.location.href;
if (href && href.match(/http:\/\/(www\.)?domain\.com\/(index\.php)/i)) {
changeScreen();
}
},
changeScreen : function() {
// make changes to the screen
// note the "window.content.document) in the first jQuery selection
myExtension.jq("#left .box:eq(0)", window.content.document).after('');
// note the use of "this" to use the search results as the context
myExtension.jq("#right", window.content.document).each(function() {
myExtension.jq("tr td", this).append('MATCH!');
});
}
}

Suspend Default Event in jQuery

I am trying to delay the default event or events in a jQuery script. The context is that I want to display a message to users when they perform certain actions (click primarily) for a few seconds before the default action fires.
Pseudo-code:
- User clicks link/button/element
- User gets a popup message stating 'You are leaving site'
- Message remains on screen for X milliseconds
- Default action (can be other than href link too) fires
So far, my attempts look like this:
$(document).ready(function() {
var orgE = $("a").click();
$("a").click(function(event) {
var orgEvent = event;
event.preventDefault();
// Do stuff
doStuff(this);
setTimeout(function() {
// Hide message
hideMessage();
$(this).trigger(orgEvent);
}, 1000);
});
});
Of course, this doesn't work as expected, but may show what I'm trying to do.
I am unable to use plugins as ths is a hosted environment with no online access.
Any ideas?
I would probably do something like this.
$("a").click(function(event) {
event.preventDefault();
doStuff(this);
var url = $(this).attr("href");
setTimeout(function() {
hideMessage();
window.location = url;
}, 1000);
});
I'm not sure if url can be seen from inside the timed function. If not, you may need to declare it outside the click handler.
Edit: If you need to trigger the event from the timed function, you could use something similar to what karim79 suggested, although I'd make a few changes.
$(document).ready(function() {
var slept = false;
$("a").click(function(event) {
if(!slept) {
event.preventDefault();
doStuff(this);
var $element = $(this);
// allows us to access this object from inside the function
setTimeout(function() {
hideMessage();
slept = true;
$element.click(); //triggers the click event with slept = true
}, 1000);
// if we triggered the click event here, it would loop through
// this function recursively until slept was false. we don't want that.
} else {
slept = false; //re-initialize
}
});
});
Edit: After some testing and research, I'm not sure that it's actually possible to trigger the original click event of an <a> element. It appears to be possible for any element other than <a>.
Something like this should do the trick. Add a new class (presumably with a more sensible name than the one I've chosen) to all the links you want to be affected. Remove that class when you've shown your popup, so when you call .click() again your code will no longer run, and the default behavior will occur.
$("a").addClass("fancy-schmancy-popup-thing-not-yet-shown").click(function() {
if ($(this).hasClass("fancy-schmancy-popup-thing-not-yet-shown"))
return true;
doStuff();
$(this).removeClass("fancy-schmancy-popup-thing-not-yet-shown");
var link = this;
setTimeout(function() {
hideMessage();
$(link).click().addClass("fancy-schmancy-popup-thing-not-yet-shown";
}, 1000);
return false;
});
Probably the best way to do this is to use unbind. Something like:
$(document).ready(function() {
$("a").click(function(event) {
event.preventDefault();
// Do stuff
this.unbind(event).click();
});
})
This might work:
$(document).ready(function() {
$("a").click(function(event) {
event.preventDefault();
doStuff(this);
setTimeout(function() {
hideMessage();
$(this).click();
}, 1000);
});
});
Note: totally untested

Categories