PDA

View Full Version : replace()



Schmoopy
11-29-2008, 04:57 PM
Hi, I'm trying to get the replace() method to work for me - it is working, but not exactly how I want it to.

I want the replace method to run on mouseover, as a substitute for Firefox's content feature, so it will work on different browsers.

I have it working, but at the moment when I mouseover it's going to a new page, instead of just replacing the text that's already there, here's my code:



<script type="text/javascript">
function changeText(){
var str="continue reading";
document.write(str.replace(/continue reading/, "continue reading..."));
}
</script>

<a href="guides-maintenance-f3.html" onmouseover="changeText();">continue reading</a>



Hope you can help a beginner out,

Thanks,

Jack

boogyman
11-29-2008, 05:40 PM
<script type="text/javascript">
var el = document.getElementById('guides-maintenance');
el.onmouseover = function() {
el.nodeValue = el.replace(/continue reading/, 'continue reading...');
}
</script>
<a href="guides-maintenance-f3.html" id="guides-maintenance">continue reading</a>

Twey
11-29-2008, 07:05 PM
Instant memory leak, just add pants DOM implementation. Also, it's the nodeValue of the text node inside the element that you want, and, at the point where that script runs, the element doesn't yet exist.

This isn't actually a problem with replace() at all: the problem is your use of document.write(). In fact you don't even need replace():
<a href="guides-maintenance-f3.html" id="guides-maintenance">continue reading</a>
<script type="text/javascript">
document.getElementById("guides-maintenance").onmouseover = function() {
this.firstChild.nodeValue += "...";
};
</script>

Schmoopy
11-29-2008, 08:26 PM
Firstly, thanks very much for the help guys, and using Twey's code works, but 2 problems still need to be sorted.

I want it to remove the dots on mouseout, and also, the first time you mouse over it, it doesn't work, only on the second mouseover does it start adding dots, hope you can help,

Thanks,

Jack

Twey
11-29-2008, 10:59 PM
<a href="guides-maintenance-f3.html" id="guides-maintenance">continue reading</a>
<script type="text/javascript">
var e = document.getElementById("guides-maintenance");

e.onmouseover = e.onmouseout = (function(other) {
return function() {
var e = this.firstChild,
v = e.nodeValue;
e.nodeValue = other;
other = v;
};
})("continue reading...");

e = null;
</script>

Schmoopy
11-29-2008, 11:23 PM
Hey, thanks again, but it's now saying "continue reading" on mouseover, and "continue reading...", on mouse out.

So like that, but just the other way round :)

Thanks,

Jack.

Twey
11-30-2008, 01:11 AM
Peculiar, shouldn't do that... but anyway, you can just swap the strings over.

Schmoopy
11-30-2008, 02:29 AM
Yea, I've done that, only thing now is it, with it that way, when the page first loads it says "continue reading..." and then after I mouseover once it starts working. Only thing is, I don't want it to say "continue reading..." on page load, know how to do this?

Thanks,

Jack.

Twey
11-30-2008, 09:45 AM
I must confess, I'm at a loss as to why such a thing could be occurring. Have you any other scripts on the page that could be causing the issue?

Schmoopy
11-30-2008, 12:28 PM
Well, I did put your script inside a function, so I could use it on more than one mouseover event, but I didn't think that would change anything, only other scripts I have on the page is one for a drop down menu from DD, and one I made for tabbed content. =/

Twey
11-30-2008, 12:54 PM
It sounds like that's likely the problem — most probably, your function isn't being called when it should be.

You'll notice that the script is in fact already a function. Storing it for later or multiple use is as simple as not immediately calling it:
<a href="guides-maintenance-f3.html" id="guides-maintenance">continue reading</a>
<script type="text/javascript">
function swapContent(other) {
return function() {
var e = this.firstChild,
v = e.nodeValue;
e.nodeValue = other;
other = v;
};
}

(function(e) {
e.onmouseover = e.onmouseout = swapContent("continue reading...");
})(document.getElementById("guides-maintenance"));
</script>

Schmoopy
11-30-2008, 01:03 PM
Ok thanks once again, still having problems though.

Here is my exact code now:



<script type="text/javascript">
function swapContent(other) {
return function() {
var e = this.firstChild,
v = e.nodeValue;
e.nodeValue = other;
other = v;
};
}

(function(e) {
e.onmouseover = e.onmouseout = swapContent("continue reading...");
})(document.getElementById("articleOne"));
</script>


HTML:



<a id="articleOne" onmouseover="swapContent('articleOne');" href="guides-maintenance-f3.html">continue reading</a>


I'm really not very good at this, so I didn't know whether I had to pass "articleOne" into the function or what, but either way, I tried it in a few different ways but every time the Firefox error console said "e is null".

Hope this helps,

Jack.

jscheuer1
11-30-2008, 03:16 PM
This is all really overcomplicated, though I tried Twey's method from:

http://www.dynamicdrive.com/forums/showpost.php?p=172839&postcount=5

and it worked. A simpler approach would be:


<a href="guides-maintenance-f3.html" id="guides-maintenance"
onmouseover="this.firstChild.nodeValue += '...';"
onmouseout="this.firstChild.nodeValue = 'continue reading';"
>continue reading</a>

Schmoopy
11-30-2008, 03:25 PM
Thanks for that, still having issues :S - but I think it's to do with the doctype, here is the error message I'm getting from Firefox console:

setting a property that has only a getter - Line 1.

Line 1 is where my doctype is, and it's xhtml transitional, any other solution to this?

Thanks,

Jack.

jscheuer1
11-30-2008, 03:32 PM
A line 1 error often means that FF doesn't really know where the error is, it could be an onload or any event, including the mouseover/out of the id="guides-maintenance" element.

But, if you got rid of Twey's code, and are only using mine for the text changes to the id="guides-maintenance" element, that error is as regards something else.

If you want more help:

Please post a link to the page on your site that contains the problematic code so we can check it out.

Schmoopy
11-30-2008, 03:37 PM
Ok fixed it now :)

Thanks very much for your help guys.

Twey
12-01-2008, 06:09 AM
The latest failed to work because you ignored the other change I made earlier, which was to move the script after the affected element in the code.

John's works too, but contains some nasty duplication of data that, perhaps unreasonably for a case so small, sets my teeth on edge :)

jscheuer1
12-01-2008, 07:54 AM
Here's an approach that typifies (to a degree) a new method of dealing with events that I currently favor because it's AJAX(y) friendly and separates javascript and markup in a forward looking fashion, while playing well in browsers that don't support it. Perhaps even Twey's teeth :) might like it:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
#guides-maintenance span {
display: none;
}
</style>
<script type="text/javascript">
if(document.getElementById)
(function(){
var swapText = function(e){
var a = document.getElementById('guides-maintenance'), s;
if(!a || !(s = a.getElementsByTagName('span')[0])) return;
e = e || window.event;
e = e.target || e.srcElement;
s.style.display = e == a || e == s? 'inline' : '';
};
if(document.addEventListener)
document.addEventListener('mouseover', swapText, false);
else if(document.attachEvent)
document.attachEvent('onmouseover', swapText);
})();
</script>

</head>
<body>
<div>
<a href="guides-maintenance-f3.html" id="guides-maintenance">continue reading<span>...</span></a>
</div>
</body>
</html>

Twey
12-01-2008, 10:49 AM
It can actually be done entirely in CSS, in this instance:
a#guides-maintenance span {
display: none;
}

a#guides-maintenance:hover span {
display: inline;
}
<a href="guides-maintenance-f3.html" id="guides-maintenance">continue reading<span>...</span></a>A JS behaviour can be used to lend support to IE6, if required.

Schmoopy
12-01-2008, 12:51 PM
Thanks for all your replies, I've now got it fixed,

Gracias, Dank, Merci etc...

jscheuer1
12-01-2008, 04:50 PM
For Twey and I, sometimes it's just fun to beat something like this to death:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
#guides-maintenance span {
display: none;
}
#guides-maintenance:hover span {
display: inline;
}
</style>
<!--[if lt IE 7]>
<script type="text/javascript">
document.attachEvent('onmouseover', function(){
var a = document.all['guides-maintenance'], s, e;
if(!a || !(s = a.all.tags('span')[0])) return;
e = event.srcElement;
s.style.display = e == a || e == s? 'inline' : '';
});
</script>
<![endif]-->

</head>
<body>
<div>
<a href="guides-maintenance-f3.html" id="guides-maintenance">continue reading<span>...</span></a>
</div>
</body>
</html>

Twey
12-02-2008, 10:26 AM
Actually, the JS isn't necessary at all, since that's an <a>. If it were another element, it would be. :) My error, sorry.

I notice you've started indenting recently, and I thoroughly approve, but conventionally we indent by two spaces, four spaces, or eight spaces. When I'm writing a quick script on here I usually two-space it because it involves less hammering of the space bar, but if I use a real editor it auto-indents for me so I use four, which is more common (and de-jure standard in several languages/libraries). Is there a reason you don't indent the HTML as well?

Schmoopy
12-02-2008, 10:36 AM
Lol this "Best Scripter Battle" is hilarious :D, let's see what John says...

jscheuer1
12-02-2008, 03:28 PM
Actually, the JS isn't necessary at all, since that's an <a>. If it were another element, it would be.

You'd think, and so did I. But for some reason it wasn't. I tried it several ways:

a#id el:hover

a:hover#id el

a#id:hover el

including same without the a selector, and with and without giving the :link pseudo class in the corresponding selector for the base style, and trying visibility instead of display. I think something else is required to get IE 6 to behave as we both expect it should in this case. The css code that this reminds me of is CSS Popup Image Viewer (http://www.dynamicdrive.com/style/csslibrary/item/css-popup-image-viewer/), which does work in IE 6. But there is nested absolute positioning (of the span) within relative (of the anchor link) involved there, and it's visibility, not display. Some or all of that might be required for the effect to work in IE 6 based solely on style.

Or - I may have just missed something. :confused:

jscheuer1
12-02-2008, 03:49 PM
OK, this appears to be the minimum required for this to work in IE 6:


#guides-maintenance:hover {
background-color: transparent;
}
#guides-maintenance span {
visibility: hidden;
}
#guides-maintenance:hover span {
visibility: visible;
}


But to have the effect work out well in FF (presumably others) at the same time, and without resorting to conditional styles in IE 6:


#guides-maintenance {
position: relative;
}
#guides-maintenance:hover {
background-color: transparent;
}
#guides-maintenance span {
visibility: hidden;
position: absolute;
}
#guides-maintenance:hover span {
visibility: visible;
}



But if you want the traditional link underline, and the ability to follow the link/span combo with plain text, this seems the minimum cross browser method:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
#guides-maintenance {
text-decoration: none;
}
#guides-maintenance:hover {
background-color: transparent;
}
#guides-maintenance span {
visibility: hidden;
}
#guides-maintenance:hover span {
visibility: visible;
}
</style>
</head>
<body>
<div>
<a href="guides-maintenance-f3.html" id="guides-maintenance"><u>continue reading</u><span><u>...</u></span></a> more text here
</div>
</body>
</html>

But it's not valid strict. Transitional would validate.

P. S. About the indenting, it reminds me of how I kept my room in my youth - a mess. Sometimes my friends would 'do me a favor' and straighten things up for me. I couldn't find anything for a week after that. Now I require order (that I impose) in my surroundings so as to be able to keep track of things. I believe a similar dynamic is at work now with my coding style.

It used to be that with properly indented code, I could never see what was happening. I think this was partly because I had no idea what it meant, and partly because I often saw code that had a mishmash of different indenting styles. So I usually just had to get rid of all indents to make sense of it.

Now that I write my own code so often, I frequently find it helpful (and even pleasant at times) to order it in at least a rudimentary fashion. But I still dislike wasted space, and my editor doesn't auto indent except in a way that I perceive as counterintuitive to my writing and editing style.

Twey
12-02-2008, 05:08 PM
I think the key might be in :link:
#guides-maintenance:link {
text-decoration: underline;
}

#guides-maintenance:link span {
visibility: hidden;
}

#guides-maintenance:link:hover span {
visibility: visible;
}

jscheuer1
12-02-2008, 05:14 PM
I tested something like that idea and it did not work. But I didn't think to apply two pseudo classes at once like your code shows. I just tried it, no joy in IE 6. Incidentally, in FF - though it works of course, the link underline of the span is visible at all times.


The concept done as I last had (more or less) can be made to validate strict:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
a {
text-decoration: none;
}
a span {
text-decoration: underline;
}
a:hover, a:hover .ext {
background-color: transparent;
visibility: visible;
}
a .ext {
visibility: hidden;
}
</style>
</head>
<body>
<div>
<a href="guides-maintenance-f3.html"
id="guides-maintenance"><span>continue reading</span><span
class="ext"><span>...</span></span></a>
more text here
</div>
</body>
</html>

Which is cross browser as well and deals nicely with link underline and layout space.