I'm making a full-screen slider with maximage & cycle that (so far) does the following:

  • Compares a given URL hash against each slide's ID and loads a match, if found,
  • Appends the first slide's ID to the address bar as a hash, if none is specified,
  • Replaces, rather than appends, a history entry when browsing through the slides, as well as updating the location hash.

Here's the main bulk of code...

jQ(function(){
    // Globals
    var s,
        slideIDs = {};
    // Populate slides object
    jQ('#slides').children('div').each(function(i) {
        s = jQ(this).attr('id').replace(/\ /g, '-');
        slideIDs[s] = i;
    });
    // Find slide via hash, go to first if !valid
    function getSlide(){
        if ( slideIDs[window.location.hash.substring(1)] >= 0 ) {
            var nxtSlide = slideIDs[window.location.hash.substring(1)];
            return nxtSlide;
        } else {
            return 0;
        }
    };
    // Post-slide hash handling
    (function(namespace) { // Closure to protect local variable "var hash"
        if ('replaceState' in history) { // html5 support
            namespace.replaceHash = function(newhash) {
                if ((''+newhash).charAt(0) !== '#') newhash = '#' + newhash;
                history.replaceState('', '', newhash);
            }
        } else {
            var hash = location.hash;
            namespace.replaceHash = function(newhash) {
                if (location.hash !== hash) history.back();
                location.hash = newhash;
            };
        }
    })(window);

...the maximage/cycle part...

    jQ('#slides').maximage({
        cycleOptions: {
            startingSlide: index,
            cssTransitions: true,
            after: onAfter,
            fx: 'fade',
            speed: 210,
            timeout: 0,
        },
    });
    function onAfter(el, next_el, opts) {
        jQ(el).removeClass('active');
        jQ(next_el).addClass('active');
        var nextHash = jQ(next_el).find('.slideLink').text().toLowerCase().replace(/\ /g, '-');
        window.replaceHash(nextHash);
    };

...and finally the hashchange part...

    jQ(window).bind('hashchange', function() {
        var nextSlide = getSlide();
        jQ('#slides').cycle(nextSlide);
    })
});

It's working well, apart from a couple of issues:

  1. In HTML4 browsers - if a hash is not specified - on page load, the first slide's ID will be added to the hash, but an unwanted extra history entry is also created,

  2. And when the hash is manually changed, the slides transition without reloading the page, but a new history entry is created again.

I've a feeling I'm close, but I can't figure it out. Does anyone have any ideas as to how I could overcome these?

Recommended Answers

All 11 Replies

Member Avatar for LastMitch

In HTML4 browsers - if a hash is not specified - on page load, the first slide's ID will be added to the hash, but an unwanted extra history entry is also created,

The Maximage2 link I just read and look at it. It's for HTML5. It means you need to put

<!DOCTYPE html>

not this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

You have to understand any HTML5 code you need to add this

<!DOCTYPE html>

so it can work correctly if not you will get some errors.

OK, the cycle link I try and used the code on there so it has nothing to do with issue you are having.

And when the hash is manually changed, the slides transition without reloading the page, but a new history entry is created again.

This is also related to Maximage2 code not cycle code.

I'm not sure I follow exactly what you're saying - I'm already using an HTML5 doctype and I'm pretty certain that isn't the problem here.
I'm not getting errors in any of the browsers I've tested.

Member Avatar for LastMitch

In HTML4 browsers - if a hash is not specified - on page load, the first slide's ID will be added to the hash, but an unwanted extra history entry is also created,

You're the one who mention HTML4 browsers?

Which one?

HTML 4.01 Strict

HTML 4.01 Transitional

HTML 4.01 Frameset

It's called tags:

http://www.w3schools.com/tags/tag_doctype.asp

Within those tags are HTML4 code.

I'm already using an HTML5 doctype and I'm pretty certain that isn't the problem here.

The code is in HTML5 so you are using HTML5 code in these tags:

HTML 4.01 Strict

HTML 4.01 Transitional

HTML 4.01 Frameset

You have to understand that those HTML4 code might not work with HTML5 code when you combine it.

I hope that make sense.

The reason I mentioned HTML4 browsers is because my client needs the website to be compatible with IE8+.

You ask which browser I'm referring to, but then list a series of doctypes - the !DOCTYPE declaration isn't a browser. I don't understand why you've listed them.

You have to understand that those HTML4 code might not work with HTML5 code when you combine it.

HTML4 will almost always work in an HTML5 doctype, due to the inherent need for backward-compatibility.

A small list of tags that are no longer "officially" supported (i.e. may actually still be supported by any number of browser vendors that chose to) can be seen here. But I'm not using any of those.

I feel this thread is going somewhat offtopic - thanks for your time, but I'm looking for a solution to the problem outlined in my original post, rather than a discussion on version compatibility.

Member Avatar for LastMitch

I feel this thread is going somewhat offtopic - thanks for your time, but I'm looking for a solution to the problem outlined in my original post, rather than a discussion on version compatibility.

OK, I apologies for that but you didn't really explain it very clear.

Compares a given URL hash against each slide's ID and loads a match, if found,

How does the URL look like?

You didn't show anything related to a URL or how it looks like with URL with an hash?

Appends the first slide's ID to the address bar as a hash, if none is specified,

How does it append to the address bar as a hash? You didn't explain clearly from your first quesion.

Replaces, rather than appends, a history entry when browsing through the slides, as well as updating the location hash.

How does it update?

Explain to me where in your code that provide does those things?

I don't see any URL the only thing I see is a slideshow code with hash's.

Ok, for example; if I navigate to: http://www.website.com/category/categoryname, which contains the following slides:

<div id="slides">
    <div class="slide">
        <div id="slide1"></div>
    </div>
    <div class="slide">
        <div id="slide2"></div>
    </div>
    <div class="slide">
        <div id="slide2"></div>
    </div>
</div>

...in all browsers, the URL will display http://www.website.com/category/categoryname#slide1 - which is exactly correct - but HTML4 browsers (IE8, for example) will also show an unwanted history entry previous to the current, that has the location value http://www.website.com/category/categoryname. Whereas HTML5-compatible browsers omit the extra history entry.

How does it append to the address bar as a hash? You didn't explain clearly from your first quesion.

The following is called after every slide transition:

function onAfter(el, next_el, opts) {
    jQ(el).removeClass('active');
    jQ(next_el).addClass('active');
    // These two lines are the important ones...
    var nextHash = jQ(next_el).find('.slideLink').text().toLowerCase().replace(/\ /g, '-');
    window.replaceHash(nextHash);
};

And the replaceHash() function is as below:

// Post-slide hash handling
(function(namespace) { // Closure to protect local variable "var hash"
    if ('replaceState' in history) { // html5 support
        namespace.replaceHash = function(newhash) {
            if ((''+newhash).charAt(0) !== '#') newhash = '#' + newhash;
            history.replaceState('', '', newhash);
        }
    } else {
        var hash = location.hash;
        namespace.replaceHash = function(newhash) {
            if (location.hash !== hash) history.back();
            location.hash = newhash;
        };
    }
})(window);

...which should hopefully also explain how it updates the window location.

I hope this makes things a little clearer.

Member Avatar for LastMitch

I hope this makes things a little clearer.

After what you explain I don't think we are on the same page.

I think you are very creative doing this way.

But there's no way you can used a jQuery code to add a hash# on a URL and make it function.

You have to understand it's only 1 page.

The hash# is actually part of the code in jQuery on 1 page.

You can ReMod by adding the # with the slide something like this:

index.php/#slide1 
index.php/#slide2 

by doing that all the browser will appear that way.

Then you used the ReMod link and embed to button or link and if you click it will go to that #slide1, #slide2 and etc.

On the URL it will appear like this:

index.php/#slide3 

This makes more sense and much easier to modify in the future if you need to make changes.

But there's no way you can used a jQuery code to add a hash# on a URL and make it function.

I'm sorry, but that's just not correct. Javascript is the client-side language for altering browser values - the window location (which, by default, includes hash values) being one of many. I suggest you read a little more about javascript's scope before making more statements like that.

Perhaps you misunderstood my explanation, and if so I apologise - it was a verbose question I asked, so I'm not entirely without fault here - but you're clearly a more adept PHP coder than a javascript one.

This question pertains to js/jQuery only, as indicated by the 49 lines of jQuery in my question.

If you've any suggestions as to how to tackle the (solveable) issue I'm having, via the language I am clearly identifying, I sincerely welcome them.

Member Avatar for LastMitch

@chr.s

You downvoted for me saying something wrong and not helpful?

I found it rude that it took you 2 weeks to reply back?

If you are having issue still why not explain it more 2 weeks ago?

Why now?

Explain to me why it's 2 weeks wait?

As far as I'm aware there is no upper limit relating to forum-post response time. I'm generally quite busy and often, if a thread appears to be going nowhere (as is/was the case in this instance), I will revisit when I have time to do so.

I was going to apologise for offending you with a downvote, until I noticed that you had done exactly the same thing to me in return. A childish act. If the action of a downvote upsets you so much, perhaps you ought to reconsider your membership in a community where downvotes are a perfectly permissible act.

And yes, I did downvote - for the simple reason that anybody with a similar issue to the one I posted may chance upon this thread and take the following quote as fact:

But there's no way you can used a jQuery code to add a hash# on a URL and make it function.

when it's completely wrong and of no help to anybody.

Your downvote as retalliation is in no way beneficial to the public who regularly use this otherwise respectable forum for help and assistance.

Consider my second downvote as a method to draw your attention to this fact.

commented: Can you please refrain yourself downvoting me again? -2
Member Avatar for LastMitch

As far as I'm aware there is no upper limit relating to forum-post response time. I'm generally quite busy and often, if a thread appears to be going nowhere (as is/was the case in this instance), I will revisit when I have time to do so.

You're right there's no response time but it is ridiculous you disagree with my opinion 3 weeks ago and reply back last week and downvote me? With that kind of an attitude noone will even help you.

I was going to apologise for offending you with a downvote, until I noticed that you had done exactly the same thing to me in return. A childish act. If the action of a downvote upsets you so much, perhaps you ought to reconsider your membership in a community where downvotes are a perfectly permissible act.

Yes, I take it personnel. You're acting childish now.

when it's completely wrong and of no help to anybody.

I can voice my opinion, there is alot of tutorial using #hashes in jQuery but in your case it might not work.

Consider my second downvote as a method to draw your attention to this fact.

OK. Fine. Can you please refrain yourself downvoting me again?

I'm gonna flag this as a bad post if you are being hostile.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.