// ==UserScript== // @name 京东单价助手 // @namespace http://greasyfork.org/ // @version 1.0 // @description 京东商品列表页面的增强程序,增强了显示单价功能,帮助你在京东找到最便宜的商品 // @author Yarmu // @include http*://search.jd.com/* // @include http*://list.jd.com/* // @include http*://item.jd.com/* // @grant none // @supportURL https://greasyfork.org/zh-CN/scripts/30522-%E4%BA%AC%E4%B8%9C%E5%8D%95%E4%BB%B7%E5%8A%A9%E6%89%8B // @downloadURL none // ==/UserScript== (function() { setInterval(addPriceTipListener, 1000); })(); function addPriceTipListener() { $('.p-price').each(function() { if (!$(this).attr('listening')) { $(this).attr('listening', '1'); addPriceTip.call(this); } }); } function addPriceTip() { $(this).unbind("DOMSubtreeModified"); var price = parseFloat($(this).find('i').html()); if (isNaN(price)) { price = parseFloat($(this).find('.price').html()); } if (!isNaN(price)) { var title = null; var index = 0; $(this).parent().find('.p-scroll .ps-wrap .ps-main .ps-item a').each(function(idx) { if ($(this).attr('class') === 'curr' && $(this).attr('title')) { title = $(this).attr('title'); index = idx; return false; } }); var unit = getUnit(title, price); if (unit === null && index === 0) { title = $(this).parent().find('.p-name a em').text().trim(); if (!title) { title = $('.sku-name').text().trim(); } unit = getUnit(title, price); } if (unit !== null) { var htm = ' (' + toDecimal(unit.price) + '/' + unit.unit + ')'; $(this).find('strong i').append(htm); $(this).find('.price').append(htm); } } $(this).bind("DOMSubtreeModified", addPriceTip); } function getUnit(title, price) { if (!title) return null; if (price <= 0) return null; var name = title.replace(/[((][^))]+[))]/ig, ''); var reg1 = /\b((\d+)\s*[包袋盒]?\s*[*x×]\s*)(\d+\.?\d*?)\s*(g|kg|ml|l|千克|克|毫升|升)\/?[个盒]?/ig; var reg2 = /\b(\d+\.?\d*?)\s*(g|kg|ml|l|千克|克|毫升|升)\/?[个盒]?(\s*[*x×]\s*(\d+))?/ig; var pCap = 3, pUnit = 4, pCount = 1; var reg = reg1; if (!reg.test(name)) { pCap = 1; pUnit = 2; pCount = 4; reg = reg2; if (!reg.test(name)) { name = title; pCap = 3; pUnit = 4; pCount = 1; reg = reg1; if (!reg.test(name)) { pCap = 1; pUnit = 2; pCount = 4; reg = reg2; } } } reg.lastIndex = 0; var match = null; var cap = 0; var un = ''; var isOnlyOne = !/[+|+|送]/i.test(name); while ((match = reg.exec(name))) { var capacity = parseFloat(match[pCap]); if (match.length > 4 && match[pCount]) { capacity *= parseInt(match[pCount]); } if (capacity <= 0) { continue; } var unit = match[pUnit].toLowerCase(); if (unit === 'g' || unit === '克') { capacity /= 1000; unit = 'kg'; } else if (unit === '千克') { unit = 'kg'; } else if (unit === 'ml' || unit === '毫升') { capacity /= 1000; unit = 'L'; } else if (unit === 'l' || unit === '升') { unit = 'L'; } if (un === '' || un == unit) { un = unit; cap += capacity; } if (isOnlyOne) { break; } } if (cap > 0) return { capacity: cap, unit: un, price: parseFloat(price) / cap }; else return null; } function toDecimal(x) { var f = parseFloat(x); if (isNaN(f)) { return; } f = Math.round(x * 100) / 100; return f; }