简体   繁体   中英

Get query string parameters from href in a tag

I have a page with a series of <a> links on it that look like this:

<a href="http://www.domain.com/page/other.jsf?fruit=apple&tree=pine&rock=sedimentary">click me</a>

These parameters manipulate the content for the eventual page linked to ("other.jsf") in minor ways.

As part of an A/B/n test I want to change the parameters in the href based on user behaviour on the page containing the link. So, for example, I'd want to change the fruit parameter to "orange" before it was clicked.

My problem is that the parameters change location in the string or may not exist at all for some links and the .param() function only appears to work on urls.

So far (based on another question answer) I have this, but it doesn't account for the possibility that there may be no "end_pos" or if "fruit=" is missing from the href (though this second bit seems like an easier fix with an if undefined-type function):

$('a').each(function () {
    if ($(this).attr('href').indexOf('other') > -1) {
        var hrefStr = $(this).attr('href');
        var start_pos = hrefStr.indexOf('fruit=') + 1;
        var end_pos = hrefStr.indexOf('&',start_pos); //works as long as fruit=apple is in the middle or front of the string
        var fruit = hrefStr.substring(start_pos,end_pos);
        ...
        //put modified href back in <a>
    }
});

My second problem is then identifying the same part of the original href to put the new string back into. I can probably get this after understanding the method for extracting it in the first place though.

I should also say I have no control over the .jsf pages other than via JavaScript

I used this function to do that :

function getQueryParameters (str) {
  return (str || document.location.search).replace(/(^\?)/,'').split("&").map(function(n){return n = n.split("="),this[n[0]] = n[1],this}.bind({}))[0];
}

var queryParams = getQueryParameters(myUrl);

result :

{
    "fruit": "apple",
     ...
}

Heres a way I use to extract url parameters!

var getUrlParameter = function(sParam,url) {
    var sPageURL = url;
    if(typeof(sPageURL) === 'undefined' || sPageURL == ''){
        sPageURL = decodeURIComponent(window.location.search.substring(1));
    }
    var sURLVariables = sPageURL.split('&'), sParameterName, i;

    for (i = 0; i < sURLVariables.length; i++) {
        sParameterName = sURLVariables[i].split('=');

        if (sParameterName[0] === sParam) {
            return sParameterName[1] === undefined ? true : decodeURI(sParameterName[1]);
        }
    }
};

usage

 getUrlParameter('fruit',url_after_question_mark);

Part 2 of your problem! If your parameters are known or atleast a known set you could always reconstruct the url with fresh values.

eg var params = ['fruit','tree','some_other','some_other2'];//superset of all possible parameters.

Now you could loop through this array and call getUrlParameter function with each of the parameter to see if it exists. If it exists reconstruct your url with fresh values.

Just for clarification, the function getUrlParameters will return undefined for any param not found, discard it based on typeof undefined and then reconstruct url with your new values

You could use Attribute Contains Selector [name*="value"] "a[href*=fruit]" to select a elements that contain "fruit" at href attribute, .attr(attributeName, function) , String.prototype.replace() to replace "apple" with "orange"

 $("a[href*=fruit]").attr("href", function(_, href) { return href.replace(/apple/, "orange") }) 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script> <a href="http://www.domain.com/page/other.jsf?fruit=apple&tree=pine&rock=sedimentary">click me</a> 

Instead of substr , split the params apart and work with them. Here's verbose example to help.

var url = 'http://www.domain.com/page/other.jsf?fruit=apple&tree=pine&rock=sedimentary';

/**
* Gets params from url as an object
* @param {String} url
* @return {Object}
*/
var getParams = function (url) {
    var params = {};
    var match = url.match(/\?(.*)$/);

    if (match && match[1]) {
        match[1].split('&').forEach(function (pair) {
            pair = pair.split('=');
            params[pair[0]] = pair[1];
        });
    }

    return params;
};

/**
* Converts an object of params into a query string.
* @param {Object} params
* @return {String}
*/
var paramsToString = function (params) {
    return Object.keys(params || {}).map(function (key) {
        return key + '=' + params[key];
    }).join('&');
};

/**
* Replaces url params.
* @param {String} url
* @param {Object} newParams
* @return {String}
*/
var changeParams = function (url, newParams) {
    var params = getParams(url);

    Object.assign(params, newParams);
    return url.replace(/\?(.*)$/, function () {
        return '?' + paramsToString(params);
    });
};

var urlWithNewParams = changeParams(url, {
    fruit: 'banana',
    weasel: 'yes',
});

console.log(urlWithNewParams); // http://www.domain.com/page/other.jsf?fruit=banana&tree=pine&rock=sedimentary&weasel=yes

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM