4

I'm wondering if I can set the value of an HTML object's attribute as a string that contains # character ?

The reason I want to do this is the page will have a lot of items that should scroll the page to specified elements, and I want to store the data ' which item should it scroll to? ' as a data-scrollto attribute.

So my JavaScript code -will- look like this:

function ScrollToElement(lm)
{
    var theTop  = lm.offset().top;
    $("html,body").animate({
        scrollTop: theTop/*,
        scrollLeft: 1000*/
    });
}

// .. and add click event to all such objects : 
$('.scroller').click(function(){
        var theSelector = $(this).attr('data-scrollto');
        ScrollToElement($(theSelector));
    });

so the html elements will look like :

<a class='scroller' data-scrollto='p#p-to-scroll'>Click to scroll to p</a>

is it safe ?

And as a side question, why does

$(element).data('scrollto');

does not work but

$(element).attr('data-scrollto'); 

works ?

jeff
  • 13,055
  • 29
  • 78
  • 136
  • 3
    Yes, it's safe. Maybe not really elegant though, as you mix logic and presentation a little too much. – Denys Séguret Sep 03 '13 at 17:06
  • 1
    Why `p#p-to-scroll`? Just `#p-to-scroll` isn't enough? – u_mulder Sep 03 '13 at 17:07
  • @dystroy you are right, I'm creating a portfolio for myself, and I want an easy navigation. Adding all the click()'s one by one seemed too much to me, and I would like to keep the javascript constant, whereas changing html elements. Do you think of a better way for it? – jeff Sep 03 '13 at 17:08
  • @u_mulder of course, but if it works, it works both ways, right? – jeff Sep 03 '13 at 17:08
  • @dystroy - I would argue that the data attributes are meant for this type of logical storage – Justin Bicknell Sep 03 '13 at 17:10
  • u_mulder's point is since `#p-to-scroll` is a selector for an element with the `id="p-to-scroll"`, and there can only be one element with any given id, it is superfluous to use `p#p-to-scroll` which say "select the p element with the id == p-to-scroll" – Walter Stabosz Sep 03 '13 at 17:11
  • @WalterStabosz yes you are right, however, I have faced some issues with that, in CSS. If you don't "select precise enough" while styling an element from multiple files, CSS can ignore your rules, so I've decided to go that superfluous way :) For JavaScript, you are 100% right I guess, but it's hard to change habits :) Thanks for your help though ! – jeff Sep 03 '13 at 17:14
  • 2
    I'm with @dystroy on this . . . I'd recommend using `ScrollToElement($("#" + theSelector));` instead of `ScrollToElement($(theSelector));` and have the `data-scrollto` value simply be the target element's `id` attribute. That would separate the data from the logic. – talemyn Sep 03 '13 at 17:18
  • @talemyn practical ! Since I should never use a class for that, your solution makes great sense. Thanks ! – jeff Sep 03 '13 at 17:21

2 Answers2

3

According to the W3C specs, yes, it is safe to use the U+0023 NUMBER SIGN characters (#) and the U+002E FULL STOP characters (.).

The attribute name, followed by zero or more space characters, followed by a single U+003D EQUALS SIGN character, followed by zero or more space characters, followed by the attribute value, which, in addition to the requirements given above for attribute values, must not contain any literal space characters, any U+0022 QUOTATION MARK characters ("), U+0027 APOSTROPHE characters ('), U+003D EQUALS SIGN characters (=), U+003C LESS-THAN SIGN characters (<), U+003E GREATER-THAN SIGN characters (>), or U+0060 GRAVE ACCENT characters (`), and must not be the empty string.

Read http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#attributes-0.

federico-t
  • 12,014
  • 19
  • 67
  • 111
0

Yes, you can store a hash # and . in the data attributes. You should use the proper data methods. http://api.jquery.com/jQuery.data/

var theSelector = $(this).data('scrollto');

If you can't seem to use the data method, check the version of jQuery you are using, it was introduced in version 1.2.3

Justin Bicknell
  • 4,804
  • 18
  • 26
  • The OP seems to have some problem getting `$.data` to work, and can only get the data using `$.attr`. @Cengiz: Here is a jsfiddle showing both in action: http://jsfiddle.net/sS9eF/ but you should really use `$.data`. If it's not working, there may be a problem with your HTML, or some browser compatibility issue. – Walter Stabosz Sep 03 '13 at 17:20
  • Wondering if the OP is using an outdates version of jQuery? – Justin Bicknell Sep 03 '13 at 17:23
  • The `$.data` method stores the data without actually changing the DOM node, so you wouldn't see the change in the DOM inspector. `$.attr` does change the node; I wonder if that's what OP is seeing? – Evan Davis Sep 03 '13 at 17:37
  • @JustinBicknell maybe , [@]Mathletics maybe :) I just remember something were not working about $.data, but $.attr always worked, so I never used $.data :) is it wrong ? – jeff Sep 03 '13 at 18:54
  • @CengizFrostclaw - I'd have to know more about the problem you were having with `data`, but anytime you are storing and retrieving data, then it makes more sense to use it then `attr`. Plus, you can reference in memory objects, not just strings using `data`. – Justin Bicknell Sep 03 '13 at 19:52
  • @JustinBicknell I really can't remember. If I have any other problems with that, i'll invite you to the new topic :) Thanks for all the help ! – jeff Sep 04 '13 at 14:00
  • I just ran into a similar issue: if you use `$.data` to set an element's data value, it will not add an data-attribute to the element. http://stackoverflow.com/a/15651670/740639 – Walter Stabosz Sep 05 '13 at 18:14
  • @WalterStabosz - as @Mathletics said, the data attribute does not update the dom. The `data` is a property that is stored in memory, and should be accessed as such, and not through selectors – Justin Bicknell Sep 05 '13 at 18:35