jQuery get hash of element using .on() event

2019-01-26 09:35发布

问题:

Before I get flamed with references to manuals, I have been researching this for quite some time, and keep getting dead ends. Not even sure how to debug it properly. So if any references are cited, please ensure they are well-commented and instructional. This due to me being a PHP/mySQL developer, and the JavaScript object reference model is a bit confusing to me (but definitely doing my best to learn! :) ).

I am trying to update my knowledge of jQuery using jQuery v1.7.2. Apparently the live event has been deprecated, and has been replaced by .on(). The jQuery docs say not to blend old 'click' or 'live' events with any scripts using .on().

While trying to get used to using on, I am trying to capture the hash of a given url.

The page is as follows (header has already loaded jquery.min.1.7.2.js):

    <div id='menuHolder' style="position:relative; margin-left:50px;margin-bottom:30px; padding-top:35px; min-width:600px;z-index:998;">
      <ul id="menu">
         <li><a href="#">Events</a>
            <ul id="events">
                <li>
                    <img class="corner_inset_left" alt="" src="images/menu/corner_inset_left.png"/>
                    <a id="linker21 menu" class="test AJAXcaller" href="index.php#?p=1&amp;d=AJAXcontent&i=1&amp;k=<?=$_SESSION['authcpanel']['key']?>" rel="nofollow">Upcoming Events</a>
                    <img class="corner_inset_right" alt="" src="images/menu/corner_inset_right.png"/>
                </li>
                <li><a href="#">List All Events</a></li>
                <li><a id="linkermenu" class="test AJAXcaller" href="index.php#?p=24&amp;d=AJAXcontent&i=1&amp;k=<?=$_SESSION['authcpanel']['key']?>" rel="nofollow">Add Events</a></li>
                <li class="last">
                    <img class="corner_left" alt="" src="images/menu/corner_left.png"/>
                    <img class="middle" alt="" src="images/menu/dot.gif"/>
                    <img class="corner_right" alt="" src="images/menu/corner_right.png"/>
                </li>
            </ul>
         </li>
      </ul>
    </div>

<script>
    $(document).on("click", "a.AJAXcaller", function(){ 
        alert("Goodbye!");
        alert($(this).attr("hash"));
    }); 
</script>

The first alert fires on clicking the 'Add Events' link (which has a hash), relays 'Goodbye!', then the second handler fires and relays 'undefined'. How would I access this hash?

My old code is as follows, and it works, but any ajax called pages won't have event handlers attached, which is why I'm using the .on() event. Also, If I'm going to learn how to do it PROPERLY this time ;), I don't want deprecated functions involved...

OLD CODE(works)

var linkClickAction = {
        'a.AJAXcaller' : function(element){
            element.onclick = function(){
                var locationString = $(this).attr("hash");
                locationString = locationString.replace(/.*\#(.*)/, "$1")
            var parameterString = locationString.replace(/.*\?(.*)/, "$1"); // onclick="sndReq('j=1&q=2&t=127.0.0.1&c=5');

            var parameterTokens = parameterString.split("&"); // onclick="sndReq('j=1,q=2,t=127.0.0.1,c=5');
            var parameterList = new Array();
            for (j = 0; j < parameterTokens.length; j++) {
                var parameterName = parameterTokens[j].replace(/(.*)=.*/, "$1"); // j
                var parameterValue = parameterTokens[j].replace(/.*=(.*)/, "$1"); // 1
                parameterList[parameterName] = parameterValue;
            }
            var page = parameterList['p'];
            var key = parameterList['k'];
            var includesDir = parameterList['i'];
            var changeDiv = parameterList['d'];

            sndReq(page,key,includesDir,changeDiv,parameterString); 
            return false;       
            }
        }

    };
Behaviour.register(linkClickAction);

There was also a behaviour.js script loaded that basically handled the listener. I wasn't using jQuery at all at that time. It was nice, and FAST(tiny .js files, no extraneous code), comparatively speaking, but I hit my limit of being able to write effective JavaScript when it came to handling fancy things in my ui. So I have to load the jQuery script at page load anyways. Seeing as how it's already loaded, I'm trying to make use of it's functions instead of adding more unnecesarry scripts for my page to load. Thus I want to find a result that uses native jQuery 1.7.2 functions to accomplish this goal.

RESULTS

It turns out that jQuery 1.6+ can break when using the .attr() to find a property of a DOM object. So using .prop() was the way to go. Corrected code is as follows:

/*
Page:           rating.js
Created:        Aug 2006
Last Mod:       May 30, 2012
Modder:         Darren Maurer
*/

    function sndReq(page,key,includesDir,changeDiv,parameterString) {
        var divToChange = document.getElementById(changeDiv); // the Div that the data will be put into

        // switch Div with a loading div
        divToChange.innerHTML = '<div class="loading"><img src="images/loading.gif" title="Saskatoon.CityGuru.ca - Loading Page" alt="Saskatoon.CityGuru.ca - Loading Page" border="0"/></div>';

        if (includesDir == 1){
            //Find Current Working Directory.  Use to find path to call other files from
            /*var myloc = window.location.href;
            var locarray = myloc.split("/");
            delete locarray[(locarray.length-1)];
            var arraytext = locarray.join("/");
            */
            $.ajax({
                type: "POST",
                url: "AJAXCaller.php",
                data: parameterString,
                success: function(msg){
                    $('#'+changeDiv).html(msg);
                }
            });
        } 
    }

/* =======END AJAX FUNCTIONS================= */

/* =======BEGIN CLICK LISTENER FUNCTIONS================= */
/* Listens to any a href link that has a class containing ' AJAXcaller' */
/* ie. <a id="link1" class="test AJAXcaller" href="index.php#http://233.help?id=22&think=33" rel="nofollow">> AJAX TEST LINK <</a> */
$(document).on("click", "a.AJAXcaller", function(){
    alert($(this).prop("hash")); 
            var locationString = $(this).prop("hash");
            locationString = locationString.replace(/.*\#(.*)/, "$1")
            var parameterString = locationString.replace(/.*\?(.*)/, "$1"); // onclick="sndReq('j=1&q=2&t=127.0.0.1&c=5');

            var parameterTokens = parameterString.split("&"); // onclick="sndReq('j=1,q=2,t=127.0.0.1,c=5');
            var parameterList = new Array();
            for (j = 0; j < parameterTokens.length; j++) {
                var parameterName = parameterTokens[j].replace(/(.*)=.*/, "$1"); // j
                var parameterValue = parameterTokens[j].replace(/.*=(.*)/, "$1"); // 1
                parameterList[parameterName] = parameterValue;
            }
            var page = parameterList['p'];
            var key = parameterList['k'];
            var includesDir = parameterList['i'];
            var changeDiv = parameterList['d'];
            sndReq(page,key,includesDir,changeDiv,parameterString); 
            return false;   
}); 

hope that helps someone, it definitely was a lifesaver for me!

回答1:

Your a element doesn't have a hash attribute. try getting the href attribute and using javascript's substr and indexOf functions to split the string at the #

var href = $(this).attr("href");
var hash = href.substr(href.indexOf("#"));

You can also use

$(this).prop("hash");


回答2:

$('a.js-hash').click(function() {

    // Store hash
    var hash = this.hash;

    // Using jQuery's animate() method to add smooth page scroll
    $('html, body').animate({
        scrollTop: $(hash).offset().top
    }, 1000, function() {

        // Add hash (#) to URL when done scrolling (default click behavior)
        window.location.hash = hash;
    });

    // Prevent default anchor click behavior
    return false;
});