문제

I am experiencing some odd behavior on some JSON data i have applied to a data attribute in my HTML, i have it working using a fix but I'm not sure why i need to apply this fix. I am using jquery-1.9.0

Case 1 - working without $.parseJSON()

http://reelfilmlocations.co.uk/browse-locations/

On this page i have data attributes applied to the icons below the images, i'll use the map icon as an example map icon

the html looks like this:

    <img
       src="/images/Icons/map circle.fw.png" width="24" height="24" 
       class="icon mapLink"
       data-location='{
           "id":"<?php echo($row_rs_locations['id_loc']);?>",
            "slug":"<?php echo($row_rs_locations['slug_loc']);?>",
            "page":"<?php echo($cur_page);?>",
            "lat":"<?php echo($row_rs_locations['maplat_loc']);?>",
            "lng":"<?php echo($row_rs_locations['maplong_loc']);?>",
            "pinType":"loc",
            "name":"<?php echo($row_rs_locations['name_loc']);?>",
            "linkType":"list"
      }'
    />

The JSON Object:

{ "id":"5", "slug":"boston-manor-house-and-park", "page":"1", "lat":"51.492341", "lng":"-0.3186064000000215", "pinType":"loc", "name":"Boston Manor House and Park", "linkType":"list" }

i checked on http://jsonlint.com/ and this is indeed valid json

I have the following jquery to run when the a map icon is clicked

$('.wrapper').delegate('.mapLink','click',function() {
            var myData = $(this).data('location');
            console.log(myData); // correctly logs json object
            $('.middle_section').hide();
            $('#mapContent').show();
            createMarkerWithInfo(myData, true); 
        })

everything works as expected the data-location element is read in as json and i can use it as a json object without doing anything else


Case 2 - need to use $.parseJSON()

http://2012.reelfilmlocations.co.uk/browse-locations/

This is almost a duplicate of the above case (this version will be optimized for mobile devices)

code is pretty much the same except the click event retrieves the data-location element but as text not a json object i need to parse it using $.parseJSON(myData) before i can use it.

$('.wrapper').delegate('.mapLink','click',function() {
            //console.log('mapLink clicked');
            var myData = $(this).data('location');
            console.log(myData);// outputs text not a json object
            myData = $.parseJSON(myData) //parse the data
            console.log(myData);// outputs a JSON object
            $('.middle_section').hide();
            $('#mapContent').show();
            createMarkerWithInfo(myData, true); 
        })

I'm not understanding why in two scripts which in effext are exactly the same, i have to use $.parseJSON and on the other i dont, seems weird behaviour to me, can anyone enlighten me?

도움이 되었습니까?

해결책

Your first link, where it's working, is using jQuery 1.9.0.

Your second link, where it isn't working, is using jQuery 1.7.2.

The reason it isn't working is that the regular expression used by jQuery 1.7.2 (the version you're using on that site), which is /^(?:\{.*\}|\[.*\])$/, fails to detect that the attribute contains correct JSON and so doesn't pass it on to $.parseJSON.

The regular expression used by jQuery 1.10.2, which is /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, does correctly detect that it has JSON, and does pass it on to $.parseJSON. (That expression seems rather permissive to me, but if it passes on something invalid and the parse fails, it continues with the string.) Persumably they fixed the regex somewhere between 1.7.2 and 1.9.

Here's a test page using the JSON from the first mapLink on your page using jQuery 1.7.2:

<div id="test" data-location='{
                              "id":"1",
                              "slug":"watermans-arts-centre",
                              "page":"1",
                              "lat":"51.485768",
                              "lng":"-0.29806459999997514",
                              "pinType":"loc",
                              "name":"Watermans Arts Centre",
                              "linkType":"list"
                              }'></div>
<script>
  (function() {
    var test = $("#test");
    display("jQuery v" + test.jquery);
    display("typeof data: " + typeof test.data("location"));

    function display(msg) {
      $("<p>").html(String(msg)).appendTo(document.body);
    }
  })();
</script>

...which outputs:

jQuery v1.7.2

typeof data: string

...and here's that same page using jQuery 1.10.2, which outputs:

jQuery v1.10.2

typeof data: object

다른 팁

From the jQuery documentation:

When the data attribute is an object (starts with '{') or array (starts with '[') then jQuery.parseJSON is used to parse the string; it must follow valid JSON syntax including quoted property names. If the value isn't parseable as a JavaScript value, it is left as a string.

http://api.jquery.com/data/#data2

So it seems your second JSON data is very likely invalid.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top