【问题标题】:Too much JSON crashes browser :(太多 JSON 会导致浏览器崩溃:(
【发布时间】:2011-11-28 22:39:14
【问题描述】:

我有一个 ajax 国家/城市选择器。当我选择美国时,浏览器崩溃。呵呵!

我有一个国家的下拉列表。当我选择一个国家/地区时,会运行一个 jQuery ajax 调用,该调用会获取属于该国家/地区的城市的 JSON 响应。

当我必须在执行期间增加允许的内存时,我应该看到它的到来。这是选择英国时的 JSON 响应。

{"5947":"Aberdeen","12838":"Aberystwyth","15707":"Aldershot","18575":"Alsagers Bank","18682":"Altrincham","4863":"Andover","41802":"AOL","6471":"Armagh","18945":"Ascot","4864":"Ashby-de-la-Zouch","4865":"Ashford","5948":"Aviemore","12985":"Aylesbury","12281":"Ballymena","14446":"Banbury","12445":"Bangor","13631":"Barking","4866":"Barnet","17004":"Barnsley","16423":"Barrow-in-Furness","16254":"Basildon","12402":"Basingstoke","5826":"Bath","13289":"Beddgelert","15082":"Bedford","4868":"Belfast","4869":"Belper","13874":"Benfleet","5827":"Benson","15514":"Berkhamsted","4870":"Berwick Upon Tweed","12948":"Betws-y-Coed","18776":"Bexley","14530":"Bicester","4871":"Billericay","18436":"Birkenhead","4872":"Birmingham","14592":"Blackburn","14686":"Blackpool","12526":"Bolton","12480":"Bournemouth","13062":"Bracknell","18772":"Bradford","4873":"Braemar","4874":"Brecon","4875":"Brentwood","18820":"Brighton","14260":"Bristol","4876":"Broomfield","42004":"Burgess Hill","14654":"Burnley","4877":"Burton Upon Tren","13812":"Bury","15835":"Bury St Edmunds","16500":"Camberley","4878":"Cambridge","4879":"Canterbury","5957":"Cardiff","14443":"Carlisle","14065":"Carrickfergus","42384":"Chalgrove","5832":"Chatham","13641":"Chelmsford","4880":"Cheltenham","4881":"Chester","42879":"Chesterfield","12160":"Chichester","41768":"Chorley","14056":"Church Stretton","5949":"Cladich","4884":"Colchester","16204":"Congleton","17534":"Coniston","42888":"Corsham","4885":"Coventry","13575":"Crawley","15410":"Crewe","13913":"Croydon","4886":"Cumbernauld","13711":"Dartford","4887":"Dartmouth","5833":"Derby","17468":"Derry","4889":"Doncaster","13696":"Dorchester","15377":"Dorking","5834":"Dover","16659":"Dudley","41867":"Dumbarton","18091":"Dumfries","4890":"Dunbar","14217":"Dunblane","4891":"Dundee","14067":"Dunfermline","4892":"Durham","16058":"East Molesey","17521":"East Preston","12501":"Eastbourne","12374":"Eastrea","4893":"Edinburgh","18992":"Elgin","41763":"Ellesmere","12883":"Ely","16825":"Enfield","14510":"Epsom","5835":"Exeter","4894":"Falkirk","5836":"Falmouth","42388":"Faringdon","42034":"Farmington","14604":"Farnham","42347":"Feltham","12829":"Fleet","4895":"Forres","42315":"Frosterley","5950":"Glasgow","4896":"Glastonbury","12562":"Gloucester","15956":"Gosport","4898":"Grangemouth","12626":"Gravesend","16057":"Grays","4899":"Great Wilbraham","4900":"Greenock","12752":"Grimsby","11747":"Guildford","14506":"Guilford","11938":"Halifax","5010":"Hamilton","15553":"Harlow","41733":"Harpenden","14713":"Harrow","4902":"Hartlepool","18952":"Haslemere","13977":"Hastings","14917":"Hatfield","12529":"Haverfordwest","4903":"Haverhill","4904":"Hawarden","5951":"Hawick","11776":"Hemel Hempstead","15302":"Hereford","14999":"Hertford","41893":"Heston","16056":"Hexham","13019":"High Wycombe","13643":"Hoddesdon","5958":"Holyhead","12420":"Hornchurch","14160":"Horsham","12108":"Huddersfield","5837":"Hull End","13296":"Huntingdon","14801":"Hyde","17707":"Ilford","41721":"Inverkeithing","4905":"Inverness","5838":"Ipswich","4906":"Keighley","4907":"Kelso","18628":"Kendal","17805":"Kenilworth","4908":"Kennet","4909":"Kettering","18578":"Kidsgrove","18984":"Kilmarnock","4910":"Kingston Upon Hull","5952":"Kirkwall","18257":"Lakenheath","15425":"Lampeter","13182":"Lancaster","4911":"Laughton","13488":"Leamington","18824":"Leeds","13135":"Leek","17849":"Leicester","17716":"Leigh","12836":"Lerwick","13387":"Letchworth","4912":"Lewes","41767":"Leyland","13546":"Lichfield","5840":"Lincoln","19039":"Little Chalfont","16778":"Liverpool","13442":"Llandrindod Well","5953":"Loch Ness","12008":"London","15035":"Loughborough","15518":"Loughgall","15011":"Louth","18492":"Lowestoft","14023":"Luton","4913":"Machynlleth","12416":"Maidenhead","12230":"Maidstone","14722":"Manchester","4914":"Mansfield","4915":"Margate","4916":"Marlborough","17889":"Marlow","18870":"Melborne","16170":"Melton Mowbray","4917":"Merton","5844":"Middlesbrough","5959":"Milford","15181":"Millom","12315":"Milton Keynes","12089":"Mold","18816":"Montrose","5954":"Motherwell","18574":"Nantwich","4918":"Newark","17097":"Newbury","5845":"Newcastle","4919":"Newcastle Upon Tyne","19040":"Newport","41682":"Newquay","13629":"Northallerton","4922":"Northampton","18577":"Northwich","42209":"northwold","15080":"Norwich","5847":"Nottingham","4923":"Oban","11975":"Oldham","6474":"Omagh","17161":"Oxford","15422":"Oxshott","18627":"Penrith","4925":"Penzance","16404":"Perth","5848":"Peterborough","4926":"Plains","4927":"Plymouth","15551":"Pontypridd","14208":"Poole","4928":"Portsmouth","17642":"Portstewart","41766":"Preston","5011":"Prestwick","18579":"Radway Green","42069":"Ramsgate","11775":"Reading","14706":"Redditch","16276":"Ringwood","15522":"Ripon","14673":"Rochester","15968":"Romford","41857":"Rugby","15289":"Runcorn","17520":"Rustington","14052":"Saint Albans","16462":"Salford","4931":"Salisbury","42295":"Sandwich","17690":"Sandy","4932":"Scarborough","13975":"Seaford","12003":"Shaftesbury","18891":"Sheffield","5850":"Shrewsbury","13178":"Slough","14708":"Solihull","4935":"Southampton","4936":"Southborough","14524":"Southend-on-Sea","13970":"Southport","42260":"St Albans","5955":"St Andrews","15841":"St Asaph","18576":"St Helens","16114":"St Ives","12717":"Stafford","41746":"Staines","14051":"Stanmore","16656":"Stansted","42032":"Stevenage","5012":"Stirling","11801":"Stockport","14198":"Stockton-on-Tees","4937":"Stoke On Trent","42386":"Stranraer","4938":"Stratford-Upon-Avon","4939":"Stroud","18615":"Sudbury","11860":"Sunderland","16393":"Sutton","5960":"Swansea","12853":"Swindon","4941":"Taunton","5851":"Teeside","13973":"Telford","4943":"Truro","17702":"Virginia Water","5852":"Waddington","12059":"Wakefield","4945":"Wallingford","4947":"Wareham","5853":"Warrington","4948":"Warwick","4949":"Watford","12009":"Wellingborough","12528":"Wellington","13366":"Wells","12530":"Welwyn Garden City","16785":"Weston Under Lizard","16334":"Wetherby","18171":"Weymouth","4950":"Whitby","13308":"Whitehaven","42387":"Whitehead","5956":"Wick","17581":"Wilmslow","5854":"Wimbledon","12524":"Wimborne Minster","12551":"Winchester","15946":"Windsor","18573":"Winsford","4952":"Wisbech","4953":"Wisborough Green","12982":"Woking","18769":"Wokingham","13287":"Wolverhampton","17904":"Woodford","18086":"Woolavington","11783":"Worcester","12128":"Worthing","5961":"Wrexham","13630":"Yarm","17015":"Yeovil","11824":"York"}

这是我的 Javascipt:

$('#current-country').change(function(){ //any select change on the dropdown with id country trigger this code
            $('.select-current-city').show();
            $("#current-cities > option").remove(); //first of all clear select items
            var country_id = $('#current-country').val();  // here we are taking country id of the selected one.
            $.ajax({
                type: "POST",
                url: "<?php echo base_url()?>map/get_cities/"+country_id, //here we are calling our user controller and get_cities method with the country_id

                success: function(cities) //we're calling the response json array 'cities'
                {
                    $.each(cities,function(id,city) //here we're doing a foeach loop round each city with id as the key and city as the value
                    {
                        var opt = $('<option />'); // here we're creating a new select option with for each city
                        opt.val(id);
                        opt.text(city);
                        $('#current-cities').append(opt); //here we will append these new select options to a dropdown with the id 'cities'
                    });
                }

            });

        });

有人对我如何在浏览器中处理这么多数据有任何建议吗?

我正在使用 PHP (Codeigniter)、MySQL 和 jQuery。

【问题讨论】:

  • 多少数据? HTTP 响应的大小是多少? (检查浏览器开发者工具中的网络标签)
  • 只有 6K。即使是 IE 也可以处理!你的问题出在别处
  • 如果您使用自动完成框而不是下拉菜单,您可以将回调推迟到输入 2 或 3 个字母并大大减少列表大小。
  • 不要在循环中做多余的 DOM 选择。 $('#current-cities').append(opt);
  • 并像这样创建您的选项:$('&lt;option /&gt;',{val:id,text:city})。 jQuery 对此表单进行了一些优化。

标签: javascript jquery json


【解决方案1】:

我建议您创建一个新的option 节点数组,然后en masse 附加它们。一次只做一个可能会害死你。

var newOptions = [];
$.each(cities,function(id,city)    {
     var opt = $('<option />', { "val": id, "text": city }); 
     newOptions.push(opt[0]);  //need to push actual dom node - thanks RightSaidFred
});

$('#current-cities').append(newOptions);

或者这应该清除下拉列表中的先前选项吗?如果是这样:

$('#current-cities').html(newOptions);

【讨论】:

  • 你不能这样使用.join()。你最终会得到"[object Object][object Object][object Object]..."
  • @RightSaidFred - 刚刚意识到 - 看起来答案可能是 less jQuery :)
  • 您可以按照以前的方式进行操作,但您只需要将本机 DOM 元素推送到数组中,然后跳过 .join()。如果 jQuery 接收到一个数组,它将使用其内容填充 jQuery 对象。或者您可以先使用var newOptions = $();,然后再使用newOptions.push(...),尽管.push() 不受官方支持。
  • @RightSaidFred - 我试过这样,但没有。 $(DD).append(arrayOfDomNodes); 给出错误 Uncaught Error: NOT_FOUND_ERR: DOM Exception 8
  • @RightSaidFred - 谢谢。我将不得不看看 PushStack。您之前的评论为我解决了问题,并导致了最近的编辑。
【解决方案2】:

首先仔细检查您是否多次发出相同的 AJAX 请求。

一种快速简便的解决方案是将您的 AJAX 请求拆分为多个。首先将其一分为二,如果这还不够,则将它们除以 3 或更多。

然后,您可以检查哪种 JSON 大小适合您,并使用那个。或者您可以让您的 php 根据城市总数确定需要多少请求。

对于非常大的列表,我必须将请求分成 100 个项目。第一个请求我会得到第一个列表以及一些数据,指示我必须发出多少请求才能获得完整列表,附加新节点,然后我会发出剩余的请求,直到我得到完整列表.

【讨论】:

    【解决方案3】:

    我不明白这会给你带来怎样的崩溃。在这里,我正在做最糟糕的事情,而且速度非常快:

    http://jsfiddle.net/HZnYQ/

    每次你选择一些东西时,我都会一个一个地删除所有元素,然后一个一个地附加它们,它仍然是即时的。实际上我的 CPU 甚至没有记下它。

    【讨论】:

      猜你喜欢
      • 2014-03-09
      • 1970-01-01
      • 1970-01-01
      • 2013-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多