JQuery replaceWith() troubles

Hi, I’m just starting with Javascript and am testing out a few things.

I’ve set up two buttons to dynamically load in content. However for some reason the content only loads on the first time you click a button. The transition function does receive the correct variables however. The fade0ut animation also doesn’t take affect whilst the replaceWith() function is inside the transition function. Can you help me out?

HTML:

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<title>Javascript Transition Test</title>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js" type="text/javascript"></script>
    </head>

	<body>
    	<div id="navbar">
        	<button name="Page1">Page1</button><button name="Page2">Page2</button>
        </div>
		<div id="content">
        	<p>This is the content for the first page.</p>
		</div>
        <script src="script.js"></script>
	</body>
</html>

Javascript:

var page1 = "<p>This is the content for the first page.</p>";
var page2 = "<p>This is the content for the second page.</p>";

$("button[name=\\"Page1\\"]").click(function () {
	transition(page1);
});

$("button[name=\\"Page2\\"]").click(function () {
	transition(page2);
});

function transition(newPage) {
	$("#content").fadeOut(1000, $("#content").replaceWith(newPage));
	$("#content").fadeIn(1000);
};

If you’re just starting to learn javascript, you’ll probably be better off in the long run learning the basics of javascript first before playing with jQuery.

jQuery is just a bunch of code that someone has prewritten for you to perform certain tasks. There is nothing you can do with jQuery that you cannot do with plain javascript.

This is one way of doing it without jQuery.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
        <title></title>
        <style type="text/css">
            #ssContainer div {
                display: none;
                filter:alpha(opacity=100);
                opacity: 1;
            }
        </style>
        <script type="text/javascript">
            var curDiv = 0;
            var fadeTimer;
            var speed = 50;
            var opacStep = 0.5;
            var dirn = -1;
            var curOpac = 10;
            function fade(){
                if(fadeTimer){clearInterval(fadeTimer);}
                fadeTimer = setInterval(setOpacity,speed);
            }
            function setOpacity() {
                curOpac = curOpac + (opacStep * dirn);
                if(curOpac < 0){
                    swapDiv();
                    curOpac = 0;
                    dirn = 1;
                    fade();
                    return;
                }
                if(curOpac > 10){
                    curOpac = 10;
                    clearInterval(fadeTimer);
                    dirn = -1;
                    return;
                }
                setOpacityCSS();
            }
            function swapDiv(){
                for(i=0; i < oSsDivs.length; i++){
                    oSsDivs[i].style.display = 'none';
                }
                curDiv = newDiv;
                setOpacityCSS();
                oSsDivs[curDiv].style.display = 'block';
            }
            function setOpacityCSS(){
                if(typeof(oSsDivs[curDiv].style.opacity) == 'string'){
                    oSsDivs[curDiv].style.opacity = curOpac/10;
                } else {
                    oSsDivs[curDiv].style.filter = 'alpha(opacity=' + curOpac*10 + ')';
                }
            }
            window.onload=function(){
                oSsDivs = document.getElementById('ssContainer').getElementsByTagName('div');
                oSsDivs[curDiv].style.display = 'block';
                //assign the buttons' onclick
               var btnPagesO = document.getElementById('btnPagesCont').getElementsByTagName('button');
               for(i=0; i<btnPagesO.length; i++){
                   btnPagesO[i].num = i;
                   btnPagesO[i].onclick = function(){
                       newDiv = this.num;
                       fade();
                   }
               }
            }
        </script>
    </head>
    <body>
        <div id="ssContainer">
            <div>This is page 1</div>
            <div>This is page 2</div>
            <div>This is page 3</div>
            <div>This is page 4</div>
            <div>This is page 5</div>
        </div>
        <div id="btnPagesCont">
            <button>Show page 1</button>
            <button>Show page 2</button>
            <button>Show page 3</button>
            <button>Show page 4</button>
            <button>Show page 5</button>
        </div>
    </body>
</html>

Thanks man, I would say I know the basics, and I understand what jQuery is. I’d just rather achieve something with 1 line of code rather than 20 but there isn’t much point if I cant get it to work. Thanks for your help, it’s appreciated, it would definitely be useful if a need to result to writing my own animation functions, it may be even easier.

At the same time it would be nice to know what’s wrong with my jQuery if anyone can help.

If you look at the “back end” jQuery code to do what you want you’ll probably find that a lot more than 20 lines of code are being executed in the “background” by jQuery.

If you want to create an “illusion” of fewer lines of code, you could put all the code I posted in a separate javascript file and then call it using just a single line of code in your html file.

I’m not sure how to fix your jQuery code. Hopefully someone else can help you on that one.

Yes, I know. Sorry if appear to be rude, I have intentions of doing so. Thanks for taking you time to help out, the plain javascript example is quite useful.

no harm done - I didn’t see your post as being rude :slight_smile:

I just wanted to make the point (that a lot of “noobies” might not be aware of) that in many cases the amount of code run by jQuery functions could be significantly more than the amount of code written in plain javascript to perform the same task.

Yes, the difference is you didn’t write that code. I thought that would save time but it has proven to make debugging difficult.

Yes, the difference is you didn’t write that code. I thought that would save time but it has proven to make debugging difficult.

yep, jQuery and other js frameworks are designed to basically save coders’ time in a production environment where you are routinely churning out web pages with js functionality.

To be honest, I have hardly ever used jQuery - mainly because in my particular circumstances I don’t need to use a js framework to do what I want. Over the years I have built my own js library of “common” tasks/functions and I just tweak them to suit particular situations where needed.

The danger with jQuery is that many noobies to js try to use it as a shortcut to learning javascript, and I’m not saying that is what you are doing, and more often than not when they get stuck, they have little js foundation knowledge to help them get unstuck.

Turns out I was replacing the div I was trying to select. Sorry I can get a bit stubborn.

var page1 = "<div id=\\"content\\" style=\\"display: none;\\"><p>This is the content for the first page.</p></div>";
var page2 = "<div id=\\"content\\" style=\\"display: none;\\"><p>This is the content for the second page.</p></div>";

$("button[name=\\"Page1\\"]").click(function () {
	transition(page1);
});

$("button[name=\\"Page2\\"]").click(function () {
	transition(page2);
});

function transition(newPage) {
	$("#content").fadeOut(1000, function () {
		$("#content").replaceWith(newPage)
		$("#content").fadeIn(1000);
	});
	
};

Cleaner Solution:

var page1 = "<p>This is the content for the first page.</p>";
var page2 = "<p>This is the content for the second page.</p>";

$("button[name=\\"Page1\\"]").click(function () {
	transition(page1);
});

$("button[name=\\"Page2\\"]").click(function () {
	transition(page2);
});

function transition(newPage) {
	$("#content").fadeOut(1000, function () {
		$(this).html(newPage).fadeIn(1000);
	});
	
};