user2645830
user2645830

Reputation: 362

Object HTMLAnchorElement] has no method 'attr'

I want to prepend every menu item with URL present in the browser( have to do it because of some url redirecting stuff). But its giving error in the line mentined below. What am I doing wrong? What is the correct way?

          $(window).load(function () {
            var Home = window.location.pathname;
            alert(Home);
            path = $("#menu ul li a");

            $.each(path, function (key, value) {
                console.log(value);
                alert(value);
            //These line give error: 
            //Object [object HTMLAnchorElement] has no method 'attr'
                var link =  value.attr("href");
                value.attr("href", Home + link );
            });


        });

HTML

 <div class="menu" id="menu">
    <ul>
        <li><a href="Index.html">Home</a></li><div class="menuline"></div>
        <li><a href="Products.html">Products</a></li><div class="menuline"></div>
        <li><a href="Albums">Photos</a></li><div class="menuline"></div>
        <li><a href="#">Contact</a></li><div class="menuline"></div>
    </ul>

Upvotes: 0

Views: 573

Answers (3)

Ja͢ck
Ja͢ck

Reputation: 173612

TL;DR - You can remove that code altogether.

Each element inside a jQuery object is actually a DOM element, so when you traverse it using $.each() you will be working with the actual DOM element and not the nicely wrapped goodness of jQuery. Instead of $.each() you could use $.fn.each():

$("#menu ul li a").each(function() {
    // this references the DOM element and we change its 'href' attribute.
    this.setAttribute('href', Home + this.getAttribute('href');
});

That said, when you have <a href="bla.html">...</a>, internally the href property already starts with window.location.pathname because your links are taken relative to the current document.

Update

You can also use the .attr(name, fn) method like so:

$('menu ul li a').attr('href', function(_, value) {
    return Home + value;
});

Upvotes: 1

Adil
Adil

Reputation: 148150

You need jQuery object instead of Dom to call attr() as each() gives you DOM object not the jQuery object

$(value).attr("href", Home + link );

You can also use DOM object to directly assign value to href

value.href = Home + link;

The .each() is used directly on a jQuery collection. It iterates over each matched element in the collection and performs a callback on that object. The index of the current element within the collection is passed as an argument to the callback. The value (the DOM element in this case) is also passed, but the callback is fired within the context of the current matched element so the this keyword points to the current element as expected in other jQuery callbacks, jQuery docs.

Upvotes: 2

Arun P Johny
Arun P Johny

Reputation: 388346

Use .attr( attributeName, function(index, attr) )

$(window).load(function () {
    var Home = window.location.pathname;
    var path = $("#menu ul li a");

    path.attr('href', function (i, href) {
        console.log(this, href);
        return Home + href
    })
});

Demo: Fiddle

Cause of the problem is value is a dom element reference which does not have the .attr() method, it is provided by jQuery object. So you need to use the jQuery wrapper for the value

Upvotes: 1

Related Questions