Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #30294

Re: A few problems with looping thru a set of elements with thesame"name" specifier.

From Stefan Weiss <krewecherl@gmail.com>
Newsgroups comp.lang.javascript
Subject Re: A few problems with looping thru a set of elements with thesame"name" specifier.
Date 2016-04-18 22:54 +0200
Organization albasani.net
Message-ID <nf3hhc$g4$1@news.albasani.net> (permalink)
References <571371bd$0$5928$e4fe514c@news.xs4all.nl> <nf035v$b42$1@news.albasani.net> <5713bf9d$0$5947$e4fe514c@news.xs4all.nl> <nf36i5$an2$1@news.albasani.net> <57152723$0$5866$e4fe514c@news.xs4all.nl>

Show all headers | View raw


R.Wieser wrote:
>> I just checked in Chromium and Firefox, and neither of them
>> just add elements to `document` by their `name` attributes...
> 
> I'm not quite sure about what you are trying to saying there ...   I'm
> trying to *refer* to elements, not add them.
> 
>> maybe I misunderstood what you were talking about.
> 
> No, I think you got it right.  At least, you seemed to do when you referred
> to the DIV element not recognising the "name" attribute (did not yet test
> that though).

I see from the code you posted that your named element is an image. IMG
elements are special in that references to them will indeed be added to the
`document` object if they have a `name` attribute. There are only a handful
of other elements with similar shortcuts: APPLET, OBJECT, EMBED, FORM, IFRAME.
Other elements can be named, but that does not make them accessible via
`document.{name}`: I had only tested INPUT and A earlier, and wrongly
concluded that named elements just don't show up on `document` in Firefox
and Chrome.

The whole thing is almost certainly a legacy feature that had to be kept in
the standard because many existing scripts rely on it. But it is in the
standard, and documented in detail here:

https://html.spec.whatwg.org/multipage/dom.html#dom-tree-accessors
(at the end of section 3.1.3)

This section also defines that either a single element or an HTMLCollection
of elements is returned, depending on the number of elements with that name.


> <script language="JavaScript">
> var i = 0;
> function nextSlideImage() {
>   alert(document.slide.length);
>   for (i=0; i<document.slide.length;i++) {
>     if (!document.slide[i].hasAttribute("slide"+
> ++document.slide[i].slideIndex)) document.slide[i].slideIndex=1;
>     document.slide[i].src =
> document.slide[i].getAttribute("slide"+document.slide[i].slideIndex);
>   }
>   setTimeout("nextSlideImage()",3000);
> }
> window.onload=nextSlideImage;
> </script>
> 
> <img name="slide" src="..."
>   slide1="..."
>   slide2="..."
>   slide3="..."
> />
> 
> One remark/warning though : I'm *not* looking for any "hey, just use {fill
> in your poisson} instead !" response.  I'm trying to get the above to run,
> or, if that is not possible, understand why it won't.
> 
> In other words: although a working end-product is icing on the cake, I'm
> much more interrested in learing what happens (or not happens) with that
> code -- specifically with parts thereof -- and why (which is why I was/am
> hesitant to even mention what the script is supposed to do).

Showing the code helped me understand the context better. Now that I can see
what's going on, it seems there are two situations that aren't handled
correctly:

1) When there is no image with the name "slide" - then `document.slide` is
undefined and `document.slide.length` throws a ReferenceError.

2) When there is exactly one such image, `document.slide` is the image
object itself and `document.slide.length` is undefined (images don't have a
`length` property), so the loop is not entered.

Both of these can be solved by using getElementsByName(), which always
returns an array-like collection (which may or may not contain items):

function nextSlideImage ()
{
    var slides = document.getElementsByName("slide");
    for (var i = 0; i < slides.length; ++i) {
        var slide = slides[i];
        ++slide.slideIndex;
        if (!slide.hasAttribute("slide" + slide.slideIndex)) {
            slide.slideIndex = 1;
        }
        slide.src = slide.getAttribute("slide" + slide.slideIndex);
    }
    setTimeout("nextSlideImage()",3000);
}

As requested, this is the same basic approach, with only minor adjustments
for readability.

There are still issues:

* The original code doesn't declare the `i` variable, creating an
unnecessary global variable.

* It uses custom element attributes. This leads to validation errors (if the
HTML is ever validated, which it should), and can be avoided by using
`data-*` attributes instead.

* It augments host objects (adds a `slideIndex` property to the image
objects). While the current major browsers all support this, it has
historically led to problems that were hard to debug. In general, it's best
avoided, and there are other ways to associate custom values with objects.

* The original image (in the "src" attribute) is loaded, but then
immediately switched out for slide1. This is unnecessary.

* The original code uses `a+ ++b`, which I personally think is a capital
offense in coding ;) What this does:
  - use ++ to put `undefined` in a numeric context, giving 0
  - use ++ to pre-increment that value, giving 1
  - use + for string concatenation, giving "slide1"
All that in the conditional expression in an `if` statement.

* Referring to `document.slides[i]` six times makes the code unnecessarily
wordy. It's better to store that value in a temporary variable.

* <script language="JavaScript"> is quite obsolete now. Use
<script type="text/javascript"> or just <script> instead.


Concerning the popup blocking issue, consider using the console for
debugging instead of alert(). Calling alert() in a loop is asking for trouble.


- stefan

Back to comp.lang.javascript | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

A few problems with looping thru a set of elements with the same "name" specifier. "R.Wieser" <address@not.available> - 2016-04-17 13:22 +0200
  Re: A few problems with looping thru a set of elements with the same "name" specifier. Stefan Weiss <krewecherl@gmail.com> - 2016-04-17 15:30 +0200
    Re: A few problems with looping thru a set of elements with the same"name" specifier. "R.Wieser" <address@not.available> - 2016-04-17 18:54 +0200
      Re: A few problems with looping thru a set of elements with the same"name" specifier. Stefan Weiss <krewecherl@gmail.com> - 2016-04-18 19:46 +0200
        Re: A few problems with looping thru a set of elements with thesame"name" specifier. "R.Wieser" <address@not.available> - 2016-04-18 20:28 +0200
          Re: A few problems with looping thru a set of elements with thesame"name" specifier. Stefan Weiss <krewecherl@gmail.com> - 2016-04-18 22:54 +0200
            Re: A few problems with looping thru a set of elements withthesame"name" specifier. "R.Wieser" <address@not.available> - 2016-04-19 11:24 +0200
              Re: A few problems with looping thru a set of elements withthesame"name" specifier. Stefan Weiss <krewecherl@gmail.com> - 2016-04-19 15:42 +0200
                Re: A few problems with looping thru a set of elements withthesame"name" specifier. Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-04-19 20:08 +0200
  Re: A few problems with looping thru a set of elements with the same "name" specifier. Stefan Weiss <krewecherl@gmail.com> - 2016-04-17 15:36 +0200

csiph-web