Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

ninepints posted:

I broke something again. I've got this model

code:
        this.LocationMiniModel = function(x, y, z) {
            this.x = x;
            this.y = y;
            this.z = z;
        };
        this.LocationMiniModel.prototype.setViewAdapter = function(viewAdapter){
            this.viewAdapter = viewAdapter;
        };
        this.LocationMiniModel.prototype.append = function(element) {
            this.viewAdapter.append(element);
        };
and I'm trying to set up a view for a different model

code:
                    var category = new this.CategoryMiniModel(categoryData.name,
                                                              categoryData.uid,
                                                              locationData.uid);
                    category.setViewAdapter(
                        viewAdapter.makeCategoryMiniViewAdapter(
                            categoryData.name, category, location.append));
where location.append points to the append function in the first block of code. (The idea is that the constructor for the new view gets passed a function that it can use to append itself to a parent div.) The issue is that when location.append actually gets called, "this" points to the DOMWindow object and not the proper LocationMiniModel instance. What am I doing wrong?

Why are you sticking "this" in front of all your constructors? Anyway, double check you used new when you make that 'location' object. Which, by the way, the name location could get you into trouble if you are having trouble with this being set to the window, and your habit of throwing 'this' in front of everything, for obvious reasons. Not using new will cause this to point at the window.

If you ddi use new then check you don't have nested this contexts. The first this will point at what you think (generally) but any other this in a nested function will point back out to the root / head object. That's why the 'self = this' hack / trick is used in JS so frequently.

EDIT: try taking the 'this' off the this.Blah.prototype.blarg = function () stuff; that could be creating that nested function context which would repoint it.

Lumpy fucked around with this message at 00:26 on Jan 12, 2012

Adbot
ADBOT LOVES YOU

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Nope, that's not it. JS passes the this object according to syntax.

o.f(); passes 'o' as the this object.
var f = o.f; f(); passes the global object as the this object.

The former is known as a qualifying call, the latter is known as an unqualifying call.

If you have a modern browser, var f = o.f.bind(o); f(); should fix it. If you don't, you can use closures and Function.prototype.apply to help solve it:

code:
Function.prototype.bind = function(obj) {
    var func = this;
    return function() {
        var args = [].slice.apply(arguments);
        func.apply(obj, args);
    };
};

205b
Mar 25, 2007

Lumpy posted:

Why are you sticking "this" in front of all your constructors? Anyway, double check you used new when you make that 'location' object. Which, by the way, the name location could get you into trouble if you are having trouble with this being set to the window, and your habit of throwing 'this' in front of everything, for obvious reasons. Not using new will cause this to point at the window.

If you ddi use new then check you don't have nested this contexts. The first this will point at what you think (generally) but any other this in a nested function will point back out to the root / head object. That's why the 'self = this' hack / trick is used in JS so frequently.

EDIT: try taking the 'this' off the this.Blah.prototype.blarg = function () stuff; that could be creating that nested function context which would repoint it.

Definitely added the "new" keyword. I was using "this" since the constructors are inside separate main model/view objects and I wanted them to be visible to the controller, although I could make the constructors private and add accessor methods instead.

Suspicious Dish posted:

Nope, that's not it. JS passes the this object according to syntax.

o.f(); passes 'o' as the this object.
var f = o.f; f(); passes the global object as the this object.

The former is known as a qualifying call, the latter is known as an unqualifying call.

If you have a modern browser, var f = o.f.bind(o); f(); should fix it. If you don't, you can use closures and Function.prototype.apply to help solve it:

code:
Function.prototype.bind = function(obj) {
    var func = this;
    return function() {
        var args = [].slice.apply(arguments);
        func.apply(obj, args);
    };
};

That'd probably be the issue, I'll try it out now.

edit: It's working! Thanks for the help. Safari didn't support bind but jQuery.proxy saved the day.

205b fucked around with this message at 04:12 on Jan 12, 2012

stoops
Jun 11, 2001
*New Problem

I keep getting an error on this code. I'm guessing it doesn't like the php inserted into the javascript?

Error is: unterminated string literal

I've tried putting double quotes in the php variables but i get more errors.

code:

<script type="text/javascript">

var geoPlots = new Control.Slider ('handle-geoplots-<?php echo $entry ['Observation']['id']; ?>',
              'track-geoplots-<?php echo $entry ['Observation']['id']; ?>',
               {axis:'horizontal', minimum: 0, maximum: 200, alignX: 0, increment: 2, 

</script>

stoops fucked around with this message at 22:29 on Jan 12, 2012

Stoph
Mar 19, 2006

Give a hug - save a life.

stoops posted:

*New Problem

I keep getting an error on this code. I'm guessing it doesn't like the php inserted into the javascript?

Error is: unterminated string literal

I've tried putting double quotes in the php variables but i get more errors.

You might want to post the entire expression - it got cut off.

dizzywhip
Dec 23, 2005

stoops posted:

*New Problem

I keep getting an error on this code. I'm guessing it doesn't like the php inserted into the javascript?

I'm assuming that you accidentally forgot to copy the rest of the line of code, but in the portions that are there the strings are malformed. When it hits the first single quote in 'Observation' it ends the string, so everything afterwards is junk that causes a syntax error. Put double quotes around your strings instead.

If you still have errors after doing that, there are other problems in the part that didn't get pasted. Having PHP code inside your strings is fine (though it's not going to be executed obviously) as long as you're careful about quotes, backslashes, etc.

stoops
Jun 11, 2001

Gordon Cole posted:

I'm assuming that you accidentally forgot to copy the rest of the line of code, but in the portions that are there the strings are malformed. When it hits the first single quote in 'Observation' it ends the string, so everything afterwards is junk that causes a syntax error. Put double quotes around your strings instead.


I did what you said and it worked. Thanks.

stoops fucked around with this message at 17:06 on Jan 13, 2012

IT Guy
Jan 12, 2010

You people drink like you don't want to live!
I'm looking for a way to filter results in a <select> input in a form that is similar to how some sites filter states/provinces when you select a country.

Basically I am going to have two drop boxes and the <options> in the second drop box are determined by what the user picks in the first drop box.

I have no idea how to do this or what to even Google so hopefully someone here can lead me in the right direction.

If jQuery has a plugin or something that already does this then that would save me from rewriting something.

Strong Sauce
Jul 2, 2003

You know I am not really your father.





IT Guy posted:

I'm looking for a way to filter results in a <select> input in a form that is similar to how some sites filter states/provinces when you select a country.

Basically I am going to have two drop boxes and the <options> in the second drop box are determined by what the user picks in the first drop box.

I have no idea how to do this or what to even Google so hopefully someone here can lead me in the right direction.

If jQuery has a plugin or something that already does this then that would save me from rewriting something.

Don't know if this one works, but the word you are looking for is, "chained selects"

http://www.appelsiini.net/2010/jquery-chained-selects

Edit: but have you considered turning off and on your computer?

IT Guy
Jan 12, 2010

You people drink like you don't want to live!

Strong Sauce posted:

Don't know if this one works, but the word you are looking for is, "chained selects"

http://www.appelsiini.net/2010/jquery-chained-selects


Ah perfect, this will get me on the right path.

Strong Sauce posted:


Edit: but have you considered turning off and on your computer?


Figured it out, it wasn't plugged in :D

The Man From Melmac
Sep 8, 2008
Okay, everyone is familiar with SA's timg BBcode command, yes? Well, I'm trying to introduce something similar to a wiki I manage. I'm basically completely inept with JavaScript, but after bumbling around I finally found some code that would suit my purposes:

code:
<style type="text/css">
img.small {
  max-width: 300px;
  max-height: 300px;
  border:2px green solid;
}
img.large {
  border:2px green solid;
}
</style>

<img src="001.jpg" class="small" onclick="this.className=(this.className=='large')?'small':'large'; return false;"/>
It works great, but the problem is, most users don't have permission to use JavaScript. So what I want to do is put some JavaScript into the sidebar (which every page has) that will seek out images with a certain id or class and apply this same onclick code to each of them.

I haven't the slightest idea how to do that.

Anyone care to help me out?

The Man From Melmac fucked around with this message at 21:41 on Jan 30, 2012

FLEXBONER
Apr 27, 2009

Esto es un infierno. Estoy en el infierno.

Benjamin Black posted:

Okay, everyone is familiar with SA's timg BBcode command, yes? Well, I'm trying to introduce something similar to a wiki I manage. I'm basically completely inept with JavaScript, but after bumbling around I finally found some code that would suit my purposes:

code:
<style type="text/css">
img.small {
  max-width: 300px;
  max-height: 300px;
  border:2px green solid;
}
img.large {
  border:2px green solid;
}
</style>

<img src="001.jpg" class="small" onclick="this.className=(this.className=='large')?'small':'large'; return false;"/>
It works great, but the problem is, most users don't have permission to use JavaScript. So what I want to do is put some JavaScript into the sidebar (which every page has) that will seek out images with the small class (or ids would also work) and apply this same onclick code to each of them.

I haven't the slightest idea how to do that.

Anyone care to help me out?

document.getElementsByName("smallImagesNameGoesHere") will return an array containing all the elements with the desired class name. You can assign this to a variable, then iterate over the array and give each element the desired onClick(); method.

If you want it to happen after the page loads, just define a function that does the above, then add the call to the body tag as an onLoad function:

code:
<body onLoad="applyOnClick()">
Then, in that function:

code:
function applyOnClick() {
  var smallImages = document.getElementsByName("smallImagesNameGoesHere");

  for (i = 0; i < smallImages.length; i++) {
     smallImages[i].onClick = "this.className(this.className=='large')?'small':'large'; return false;"
  }
}
The onLoad event exists for all the following tags, if you want to put it somewhere other than the body tag:

code:
<body>, <frame>, <frameset>, iframe, <img>, <input type="image">, <link>, <script>, <style>
This should at least get you going in the right direction, even if I've completely misinterpreted what you're trying to do.

The Man From Melmac
Sep 8, 2008
Thanks for the help so far! Two things though:

1. I can't really change the body tag. Am I able to use window.onload = function(){STUFF} instead? (Edit: I realize it might already be compatible, but I want to get my reply out here while I fiddle around with the code.)

2. What would I have to change to have this apply to id's instead of classes?

The Man From Melmac fucked around with this message at 21:59 on Jan 30, 2012

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope
1. Probably
2. var someElement = document.getElementById('someId');

The Man From Melmac
Sep 8, 2008
Okay. Here's what I did. I seemed to have failed miserably, it's not working. I'm still trying to get it working as we speak, I'm sure it's something I did wrong.
code:
<style type="text/css">
img.small {
  max-width: 300px;
  max-height: 300px;
  border:2px green solid;
}

img.large {
  border:2px green solid;
}
</style>

<script type="text/javascript">
function applyOnClick() {
  var smallImages = document.getElementsByName("small");

  for (i = 0; i < smallImages.length; i++) {
     smallImages[i].onClick = "this.className(this.className=='large')?'small':'large'; return false;"
  }
 }
</script>

<script type="text/javascript">
window.onload = function(){applyOnClick()}
</script>
And the image itself.
code:
<img class="small" src="001.jpg"/>

peepsalot
Apr 24, 2007

        PEEP THIS...
           BITCH!

Element ID's must be unique in valid HTML. I wouldn't recommend using ID as a way to classify resized images.

I'd just get all img tags, and then test the class from there. You can use something like this:
code:
var imgs = document.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
    if (imgs[i].className == 'small') {
        imgs[i].onclick = function() {
          this.className = (this.className=='large')?'small':'large'; 
          return false;
        }
    }
}

Oh and it's possible to have more than one style class specified (space separated), which this code does not handle. But as long as you know you're not doing that on this page, it should be ok.

jQuery makes all this stuff a lot simpler and more robust, which is why I tend to use it for everything.

peepsalot fucked around with this message at 23:15 on Jan 30, 2012

The Man From Melmac
Sep 8, 2008

peepsalot posted:

Element ID's must be unique in valid HTML. I wouldn't recommend using ID as a way to classify resized images.

I'd just get all img tags, and then test the class from there. You can use something like this:
code:
var imgs = document.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
    if (imgs[i].className == 'small') {
        imgs[i].onClick = function() {
          this.className = (this.className=='large')?'small':'large'; 
          return false;
        }
    }
}

Oh and it's possible to have more than one style class specified (space separated), which this code does not handle. But as long as you know you're not doing that on this page, it should be ok.

jQuery makes all this stuff a lot simpler and more robust, which is why I tend to use it for everything.

Still can't get it to work. Maybe it'd be easier if I just showed you guys my test page, just keep in mind that I can't modify the body tag for the wiki I'm using this for.

On another note, if you wanted me to use jQuery instead, that'd be fine, I can embed javascript files into the wiki without difficulty (I already have in fact).

The Man From Melmac fucked around with this message at 14:32 on Nov 22, 2012

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Benjamin Black posted:

Still can't get it to work. Maybe it'd be easier if I just showed you guys my test page, just keep in mind that I can't modify the body tag for the wiki I'm using this for.


On another note, if you wanted me to use jQuery instead, that'd be fine, I can embed javascript files into the wiki without difficulty (I already have in fact).

Using jQuery, this code:

code:
jQuery('.myFancyImageClass').click( function () {
  jQuery(this).toggleClass('smallimg');
});
would attack a click handler to every element with the class "myFancyImageClass" that would toggle the "smallimg" class on and off for that element. So if it was small, it would remove the class. If it was big, it would add the class back on.

So then you could have lots of images like this:

code:
<img src="blah.jpg" alt="I start BIG!" class="fancyImageClass" />
<img src="bloop.jpg" alt="I start small" class="fancyImageClass smallimg" />
<img src="bleep.jpg" alt="I start smal as welll" class="fancyImageClass smallimg" />
and all will be well.

Lumpy fucked around with this message at 16:13 on Nov 22, 2012

peepsalot
Apr 24, 2007

        PEEP THIS...
           BITCH!

e: nevermind

peepsalot fucked around with this message at 16:35 on Nov 22, 2012

The Man From Melmac
Sep 8, 2008

peepsalot posted:

woops, onclick should be all lowercase. Sorry my JS is a little rusty.

Okay, that fixed it. Awesome. I'll try the jQuery stuff out shortly. I seem to have run into another issue, though. It looks like if a page has multiple "window.onload = function()"s, like say, one on the page and one on the sidebar, only one of them will run for some reason. Annoying.

Thanks for the all help so far.

The Man From Melmac fucked around with this message at 23:27 on Jan 30, 2012

peepsalot
Apr 24, 2007

        PEEP THIS...
           BITCH!

Benjamin Black posted:

Okay, that fixed it. Awesome. I'll try the jQuery stuff out shortly. I seem to have run into another issue, though. It looks like if a page has multiple "window.onload = function()"s, like say, one on the page and one on the sidebar, only one of them will run for some reason. Annoying.

Yeah, that's why that form of event registration sucks. And the proper way is a pain because IE does everything different from the real browsers. So yeah, use jquery.

the shortcut way to do onload in jquery is just this:
$(function() {
//do stuff here
});

ComptimusPrime
Jan 23, 2006
Computer Transformer

Benjamin Black posted:

Okay, that fixed it. Awesome. I'll try the jQuery stuff out shortly. I seem to have run into another issue, though. It looks like if a page has multiple "window.onload = function()"s, like say, one on the page and one on the sidebar, only one of them will run for some reason. Annoying.

Writing

code:
window.onload = function() { console.log('hello'); };
window.onload = function() { console.log('world'); };
Is not the proper way to do things. Understanding how this works will help you immensely in the future with JavaScript.

window is an object. onload is a member of window. Specifically, window.onload is a member that should have a pointer to a function assigned to it.

So, if you assign to it multiple times, the only one that is going to exist is the last one that was assigned to it. Assigning your listeners in HTML is generally a poor decision for multiple reasons, least of which is the problem you are running in to right now.

In HTML you can only have a single listener/handler for any event.

The proper way to handle this is:
code:
var loadHandler = function(e) {...};

// supported by all browsers except for IE<=8
if (window.addEventListener)
  window.addEventListener('load', loadHandler);

// handle special IE DOM (only necessary up to IE8
else if (window.attachEvent)
  window.attachEvent('onclick', loadHandler);
I recommend that you really try to understand why this is the right way to do things, and then go and use jQuery so you never have to bother with it again.

The Man From Melmac
Sep 8, 2008

ComptimusPrime posted:

Writing

code:
window.onload = function() { console.log('hello'); };
window.onload = function() { console.log('world'); };
Is not the proper way to do things. Understanding how this works will help you immensely in the future with JavaScript.

window is an object. onload is a member of window. Specifically, window.onload is a member that should have a pointer to a function assigned to it.

So, if you assign to it multiple times, the only one that is going to exist is the last one that was assigned to it. Assigning your listeners in HTML is generally a poor decision for multiple reasons, least of which is the problem you are running in to right now.

In HTML you can only have a single listener/handler for any event.

The proper way to handle this is:
code:
var loadHandler = function(e) {...};

// supported by all browsers except for IE<=8
if (window.addEventListener)
  window.addEventListener('load', loadHandler);

// handle special IE DOM (only necessary up to IE8
else if (window.attachEvent)
  window.attachEvent('onclick', loadHandler);
I recommend that you really try to understand why this is the right way to do things, and then go and use jQuery so you never have to bother with it again.

Well of course it's not the proper way to do things, it doesn't work after all! I'm just trying to work within the constraints of this wiki software.

Anyway... I'm trying out jQuery now. I've never used it before, so obviously this is completely wrong and broken:

The Man From Melmac fucked around with this message at 14:33 on Nov 22, 2012

peepsalot
Apr 24, 2007

        PEEP THIS...
           BITCH!

http://jsbin.com/atebuy/

The Man From Melmac
Sep 8, 2008

peepsalot posted:

http://jsbin.com/atebuy/

There we go. Perfect. Thanks. Glad I wasn't as off as I thought at the very least.

The Man From Melmac
Sep 8, 2008
Hey guys, me again. This time I have a (hopefully) simple question. I'm looking into using the innerHTML command to once again get around some restrictions of the wiki software. So I found this:

http://www.w3schools.com/htmldom/tryit.asp?filename=try_changetext

Very easy and all, but I need to do this by class rather than ID. But when I try the following code...

code:
<html>
<body>

<p class="p1">Hello World!</p>

<script type="text/javascript">
document.getElementsByName("p1").innerHTML="New text!";
</script>

<p>The paragraph above was changed by a script.</p>

</body>
</html>
It just doesn't do anything. I'm more interested in understanding why it doesn't work than anything else. Thanks.

FLEXBONER
Apr 27, 2009

Esto es un infierno. Estoy en el infierno.

Benjamin Black posted:

Hey guys, me again. This time I have a (hopefully) simple question. I'm looking into using the innerHTML command to once again get around some restrictions of the wiki software. So I found this:

http://www.w3schools.com/htmldom/tryit.asp?filename=try_changetext

Very easy and all, but I need to do this by class rather than ID. But when I try the following code...

code:
<html>
<body>

<p class="p1">Hello World!</p>

<script type="text/javascript">
document.getElementsByName("p1").innerHTML="New text!";
</script>

<p>The paragraph above was changed by a script.</p>

</body>
</html>
It just doesn't do anything. I'm more interested in understanding why it doesn't work than anything else. Thanks.

Use the getElementsByClassName method instead.

The Man From Melmac
Sep 8, 2008

Poop Delicatessen posted:

Use the getElementsByClassName method instead.

I already tried that. Didn't make a difference.

peepsalot
Apr 24, 2007

        PEEP THIS...
           BITCH!

Poop Delicatessen posted:

Use the getElementsByClassName method instead.

Or don't because IE up to and including IE 8 do not support it.

http://www.quirksmode.org/dom/w3c_core.html

This is why libraries are necessary, because loving IE hosed UP THE WEB AGAIN.

Benjamin Black posted:

Hey guys, me again. This time I have a (hopefully) simple question. I'm looking into using the innerHTML command to once again get around some restrictions of the wiki software. So I found this:

http://www.w3schools.com/htmldom/tryit.asp?filename=try_changetext

Very easy and all, but I need to do this by class rather than ID. But when I try the following code...

code:
<html>
<body>

<p class="p1">Hello World!</p>

<script type="text/javascript">
document.getElementsByName("p1").innerHTML="New text!";
</script>

<p>The paragraph above was changed by a script.</p>

</body>
</html>
It just doesn't do anything. I'm more interested in understanding why it doesn't work than anything else. Thanks.
getElementsByName returns an array of elements. arrays don't have an innerHTML property. You'll need to loop through that.

The Man From Melmac
Sep 8, 2008

peepsalot posted:

getElementsByName returns an array of elements. arrays don't have an innerHTML property. You'll need to loop through that.

So I'm going to have to do more on-load shenanigans with jQuery I assume?

peepsalot
Apr 24, 2007

        PEEP THIS...
           BITCH!

Benjamin Black posted:

So I'm going to have to do more on-load shenanigans with jQuery I assume?
Not necessarily. That wasn't the point I was making at all.

It should work ok, if you access the innerHTML of an element in the returned array. Also, if you are trying to grab an element by name, you'll want to give it a name attribute. There is a difference between getElementsByName, getElementsByClassName, and getElementsByTagName.

peepsalot fucked around with this message at 23:19 on Jan 31, 2012

The Man From Melmac
Sep 8, 2008

peepsalot posted:

Not necessarily. That wasn't the point I was making at all.

It should work ok, if you access the innerHTML of an element in the returned array. Also, if you are trying to grab an element by name, you'll want to give it a name attribute. There is a difference between getElementsByName, getElementsByClassName, and getElementsByTagName.

Okay, well, in the spirit of learning, I spent a while trying to do this myself, doing a lot of reading on w3schools and using the Tryit Editor for my experiments, but sadly I didn't really get anywhere without resorting to having a function that runs when the page loads.

So, here's what I want to know.

code:
<div class="banana"><h1>Hello World!</h1></div>
What would be the JavaScript for changing what's between this specific h1 (this is assuming this is the only h1 tag inside the div class banana), without resorting to having to run a function when the page loads?

I feel like 'function that runs when the page loads' are the training wheels I need to stop using as soon as possible.

The Man From Melmac fucked around with this message at 00:20 on Feb 1, 2012

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Benjamin Black posted:

Okay, well, in the spirit of learning, I spent a while trying to do this myself, doing a lot of reading on w3schools and using the Tryit Editor for my experiments, but sadly I didn't really get anywhere without resorting to having a function that runs when the page loads.

So, here's what I want to know.

code:
<div class="banana"><h1>Hello World!</h1></div>
What would be the JavaScript for changing what's between this specific h1 (this is assuming this is the only h1 tag inside the div class banana), without resorting to having to run a function when the page loads?

Well, you have to make sure your DOM is loaded (well, technically just those elements, but close enough) before you can manipulate them.

Then, since you are using a CLASS and not an ID, you will affect all H1 tags inside ALL elements that have the class name 'banana'. You can get fancy and limit it to DIV tags with the class, but the point stands.

What I would do is to use jQuery, and do this:

code:
jQuery(function () {
   jQuery('div.banana > h1').text("Farts");
});
I suspect you lack some fundamental understanding of the DOM, what classes and Ids are, and some other stuff that would really help you "get" this stuff. Here's some info which may be of value to you:

* you cannot manipulate an element until it exists in the DOM (Document Object Model). For example:
code:
<head>
  <script>
    document.getElementById('blah').innerText = "asdas";
  </script>
</head>
<body>
  <p id="blah">poop</p>
</body>
Will not do anything, as that P does not exist when the script runs.

* Ids are UNIQUE. Only one element in the whole DOM should have a specific Id.

* when you get elements by Id, you get ONE element back (a la getElementById) If you hosed up and gave two elements the same Id, you only get one back.

* Classes are to designate many elements as sharing some property or semantic. Many elements in the DOM can have the same class.

* When you get elements by class, you get a COLLECTION of elements, even if there happens to only be one. For example, getElementsByClassName returns an Array, regardless of how many elements there are with the class.

* Same goes for other ways of getting DOM elements... if it's possible to have more than one on the page, you get returned a collection. You sure can have more than one LI in a page, so getElementsByTagName() returns a collection. Note the plural in getElements for tag, tagName, className, etc. That tells you you are going to get a collection back from that method.

* when you get back a collection of elements, you need to manually iterate through the collection to manipulate the individual elements. Even if there's only one. You can use a for loop or fancy pants map or forEach or whatever, but you have to go in and get the stuff in the collection to change it.

Lumpy fucked around with this message at 00:32 on Feb 1, 2012

peepsalot
Apr 24, 2007

        PEEP THIS...
           BITCH!

Benjamin Black posted:

I feel like 'function that runs when the page loads' are the training wheels I need to stop using as soon as possible.
It's not really a training wheel or particularly problematic, it's how a majority of javascript is done.

The browser parses the html document in order, from top to bottom, building a DOM tree full of html element nodes as it goes. If your script block exists in the html before the browser has parsed a particular element, then that element doesn't exist as far as javascript is concerned. Using onload events delays the execution of javascript so that it occurs after the DOM tree has been completely built.

Most people from what I've seen(myself included) prefer to keep all script blocks and script includes at the top of the page, in the head, mostly as a code convention. Since none of the DOM tree has been built at this point, it's necessary to use onload events. Some people recommend just putting all your javascript at the very bottom of the page anyways (must still be inside the body tag), which has the added advantage of avoiding the DOM loading issues.

peepsalot fucked around with this message at 00:39 on Feb 1, 2012

The Man From Melmac
Sep 8, 2008
Yes, I'm aware it would affect all h1 tags inside any 'banana' class, I pointed out in the post you quoted that this is assuming there is only one banana class.

I do understand most of what you said already, id's being unique, the elements needing to be loaded before they're affected, etc. Correct me if I'm wrong, but doesn't that jquery function you showed me need to be called by something before it actually does anything?

I've been trying to avoid functions that get automatically called when the page finishes loading because it tends to make the page loading look a bit ugly. Like, I really like the thumbnail solution that was talked about earlier, but for a split second, you see the images at their full size before they're shrunk down (yeah, I can probably make a workaround for that, but I'm just giving an example why I don't want to do it here, because I have limited control over the order in which things get loaded).

So, what if there was this instead:

code:
<div id="banana"><h1>Hello World!</h1></div>
Rather than the class banana, there's the id banana. I'm assuming this would be easier and I wouldn't need to resort to jQuery. How would I affect what's behind the h1 tags inside of the id banana, without actually having to put the h1 tags back in again in the javascript code?

The Man From Melmac
Sep 8, 2008
Also, yeah, I just realized I phrased some things poorly in my last reply, particularly about the page loading. What I meant to say is, the page is probably going to load in such a way that you can see the original text for a split second if I use a function that runs when the page load completes, which is why I want to avoid doing that.

Edit: Yeah, just in case I went ahead and tried this method and it's just as I feared, it takes like a full second for the text to change.

The Man From Melmac fucked around with this message at 01:44 on Feb 1, 2012

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Benjamin Black posted:

Yes, I'm aware it would affect all h1 tags inside any 'banana' class, I pointed out in the post you quoted that this is assuming there is only one banana class.

I do understand most of what you said already, id's being unique, the elements needing to be loaded before they're affected, etc. Correct me if I'm wrong, but doesn't that jquery function you showed me need to be called by something before it actually does anything?

I've been trying to avoid functions that get automatically called when the page finishes loading because it tends to make the page loading look a bit ugly. Like, I really like the thumbnail solution that was talked about earlier, but for a split second, you see the images at their full size before they're shrunk down (yeah, I can probably make a workaround for that, but I'm just giving an example why I don't want to do it here, because I have limited control over the order in which things get loaded).

So, what if there was this instead:

code:
<div id="banana"><h1>Hello World!</h1></div>
Rather than the class banana, there's the id banana. I'm assuming this would be easier and I wouldn't need to resort to jQuery. How would I affect what's behind the h1 tags inside of the id banana, without actually having to put the h1 tags back in again in the javascript code?

You can't assume there will only be one of a class. That's what made me think you don't understand classes vs. IDs.

My jQuery function is called when the DOM is ready.

For the new HTML you posted, you do document.getElemenyById('banana').firstChild.innerText = "hurf drurf"; or something along those lines. I forget if firstChild is the right name or if its a property or method, but you get the gist.


If code executing on DOM ready takes over a second to run, the page you are working with has some serious problems.

Lumpy fucked around with this message at 01:49 on Feb 1, 2012

The Man From Melmac
Sep 8, 2008

Lumpy posted:

You can't assume there will only be one of a class. That's what made me think you don't understand classes vs. IDs.
Uh, but the class is only ever used once on the page.

quote:

For the new HTML you posted, you do document.getElemenyById('banana').firstChild.innerText = "hurf drurf"; or something along those lines. I forget if firstChild is the right name or if its a property or method, but you get the gist.

gently caress. It's not actually the first (or last) child of an id I'm trying to modify. I didn't think that was even an option when I presented the example.

Edit: It doesn't seem to be working anyway.
code:
<html>
<body>

<p id="banana"><h1>Hello World!</h1></p>

<script type="text/javascript">
document.getElementById('banana').firstChild.innerText = "hurf drurf";
</script>

</body>
</html>
Edit2: Okay, I did some reading and the thing to use with firstChild is nodevalue. That doesn't seem to be working either, however.
code:
document.getElementById('banana').firstChild.nodeValue = "hurf drurf";
Edit3: This code works, but it essentially only does the same thing the first script did, adding the <h1> tags breaks it. (Evidentally, the first child IS the div tag.)
code:
<div id="test">Hello World!</div>

<script type="text/javascript">
if (document.getElementById("test").firstChild.nodeName=="#text")
document.getElementById("test").firstChild.nodeValue="New text"
</script>

quote:

If code executing on DOM ready takes over a second to run, the page you are working with has some serious problems.
It's just pbworks, it's really code heavy. I already tested to see if my code was having an adverse effects. And 'a second' was exaggerating a bit, but you DO see the original text for a moment before it's replaced.

The Man From Melmac fucked around with this message at 02:36 on Feb 1, 2012

The Man From Melmac
Sep 8, 2008
Okay, nevermind, I figured out what I needed to do. Thanks for the help.

Adbot
ADBOT LOVES YOU

Orbis Tertius
Feb 13, 2007

Paragraph elements (<p>..</p>) can't have 'block-level' elements inside them (like h1). Use a div element instead.

What's happening is when the browser builds the DOM tree and gets to the p tag it sees there's an invalid block level element inside it and pulls it out, making it a sibling of the <p> element. (or something to that effect. In other words, by the time the JS was executed the <h1> node was no longer a child of the <p> node).

Orbis Tertius fucked around with this message at 05:59 on Feb 1, 2012

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply