Greasy Fork is available in English.
按价格过滤并排序(价格升序)秒#商品列表
// ==UserScript== // @name #东秒#价格过滤 // @version 0.4.1.4 // @icon https://www.jd.com/favicon.ico // @description 按价格过滤并排序(价格升序)秒#商品列表 // @author You! // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_addStyle // @include *://miaosha.jd.com/ // @include *://miaosha.jd.com/pinpai.html?brand_id=* // @include *://miaosha.jd.com/brand.html?brand_id=* // @include *://miaosha.jd.com/category.html?cate_id=* // @require https://code.jquery.com/jquery-3.3.1.slim.min.js // @run-at document-end // @namespace https://greasyfork.org/zh-CN/scripts/33454-#东秒#价格过滤 // ==/UserScript== (function() { 'use strict'; /**********************************************************/ //如果要过滤商品名,启用该函数,但是需要自己实现过滤逻辑: // pname 传入商品名 // catId 传入商品分类编号,编号代表的意义请自行对照#东秒#的页面地址 // 命中返回 true, 否侧返回 false /*在行首插入单行注释(//)以启用该商品名过滤函数 function filterPName(pname, cat, catId) { switch(cat) { case 'mainpage': //首页 break; case 'pinpai': //品牌秒# break; case 'brand': //品类秒# break; case 'category': //分类秒# switch(parseInt(catId)) { case 34: //潮流鞋靴 if (!/男/.test(pname)) return false; break; } break; } return true; } /**********************************************************/ //扫描页面的间隔频率时间 var timerFreq = 500; var currentPathname = location.pathname.toLowerCase(); var currentPageKey = ( currentPathname !== '/' ? 'jd_miaosha_' + location.pathname.split(/[\/\.]/)[1].toLowerCase() + '_' + location.search.split('&')[0].split('=')[1] : 'jd_miaosha_mainpage_0' ); var priceInfo = loadPagePrice(currentPageKey); uiInit(); doFilter(); //向页面右下角的浮动工具栏尾部追加价格过滤部件 function uiInit() { switch(currentPathname) { case '/': var timeline = $('#timeline a.timeline_item_link'); if (timeline.length > 0) { var waitTimelineLoad = function() { if ($('div.skwrap ul.seckill_mod_goodslist').attr('priceFiltered') === undefined) { doFilter(); } else setTimeout(waitTimelineLoad, timerFreq); }; timeline.click(function() { setTimeout(function() { $('div.skwrap ul.seckill_mod_goodslist').attr('priceFiltered', true); saveCurrentPagePrice(); waitTimelineLoad(); }, 0); }); } else { setTimeout(uiInit, timerFreq); return; } break; } var uiPos = $('#sk_mod_er ul'); if (uiPos.length > 0) { var checked = priceInfo.usePageSetting ? ' checked="true"' : ''; GM_addStyle('.fltReload{font-size:10px;font-weight:700;color:#e23a3a;background-color:#fff;border-radius:5px;padding:0px 5px}'+ '.fltCount{display:inline-block;text-align:right;width:35px}' ); uiPos.append($( '<li class="sk_mod_er_mobile" style="color:white;padding:7px;float:left;text-align:left">'+ '<nobr>正则过滤<div class="fltCount"><a class="fltReload" href="javascript:;" id="fltRetPName" title0="符合商品名过滤条件的商品数量:">刷新</a></div></nobr><br>'+ '<input id="fltNameRegx" type="text" style="width:80px;margin-top:3px" value="'+priceInfo.regstr+'"/><br/>'+ '<nobr>价格范围<div class="fltCount"><a class="fltReload" href="javascript:;" id="fltRetPrice" title0="同时符合价格范围过滤条件的商品数量:">刷新</a></div></nobr><br>'+ '<input id="fltPriceMin" type="number" style="width:80px;margin-top:3px" value="'+priceInfo.min+'"/><br/>'+ '<input id="fltPriceMax" type="number" style="width:80px;margin-top:5px" value="'+priceInfo.max+'"/><br/>'+ '<nobr><input id="fltPriceOne" type="checkbox" style="margin:6px -3px 0px 0px"'+checked+'"/><label for="fltPriceOne" style="float:right;margin-top:2px">使用独立设置</label></nobr><br/>'+ '</li>' )); $('a.fltReload,#fltNameRegx,#fltPriceMin,#fltPriceMax').change(function() { setTimeout(function() { saveCurrentPagePrice(); doFilter(); }, 0); }); $('#fltPriceOne').click(function() { var oldChecked = !this.checked; setTimeout(function() { saveCurrentPagePrice(oldChecked); $('#fltPriceMin').attr('value', priceInfo.min); $('#fltPriceMax').attr('value', priceInfo.max); doFilter(); }, 0); }); } else setTimeout(uiInit, timerFreq); } //对页面执行过滤排序操作 function doFilter() { var counts, counts2; switch(currentPathname) { case '/': //秒#首页 var g0 = $('div.skwrap'); var mg = $('div.moregoods'); //先加载“更多好货” if (mg.hasClass('o2loading')) { mg.removeAttr('style'); } else if (mg.hasClass('o2data-lazyload')) { var loadMoreGoods = function() { if (unsafeWindow.o2widgetLazyload !== undefined && unsafeWindow.o2widgetLazyload.detectRender !== undefined) { mg.attr('style', 'position:fixed;top:0;display:hidden'); unsafeWindow.o2widgetLazyload.detectRender(); } else setTimeout(loadMoreGoods, timerFreq); }; loadMoreGoods(); } else { mg.css('min-height', '0'); //价格过滤 counts = filterGoods(g0); //正在抢购 //秒#首页“即将开始”时段 if (mg.css('display') !== 'none') { mg.removeAttr('style'); counts2 = filterGoods(mg); //更多好货 } //处理“正在抢购”列表中的其他类型方块 var ul = g0.find('ul.seckill_mod_goodslist'); var all = groupObjs(ul.find('>li'), function(k, o) { o = $(o); if (o.hasClass('seckill_mod_goods')) return 0; if (o.hasClass('spsk_brand_list_item')) return 1; if (o.hasClass('brand_fullcut_item')) return 2; return 3; }); for(var i=0; i<4; ++i) { ul.append($(all[i]).remove()); } //强制加载方块内的图片 forceLoadLazyImgs(g0); } break; case '/pinpai.html': //品牌秒# case '/brand.html': //品类秒# counts = filterGoods($('div.bprd')); break; case '/category.html': //分类秒# counts = filterGoods($('div.catinfo_seckillnow')); //当天正在秒#的商品 counts2 = filterGoods($('div.catinfo_startsoon')); //明日秒#的商品 break; } if (counts && counts[0] > 0) { var fltRetPName = counts[1]; var fltRetPrice = counts[2]; if (counts2) { fltRetPName += counts2[1]; fltRetPrice += counts2[2]; } var tagA = $('#fltRetPName'); tagA.text(fltRetPName); tagA.attr('title', tagA.attr('title0') + counts[1] + (counts2 ? ' + ' + counts2[1] : '')); tagA = $('#fltRetPrice'); tagA.text(fltRetPrice); tagA.attr('title', tagA.attr('title0') + counts[2] + (counts2 ? ' + ' + counts2[2] : '')); } else setTimeout(doFilter, timerFreq); } //对页面内的一个具体分类执行过滤排序操作 function filterGoods(goodsList) { var goods = goodsList.find('li.seckill_mod_goods'); var fltRetPName = 0; var fltRetPrice = 0; if (goods.length > 0) { fltRetPName = goods.length; var groups = groupObjs(goods, function(k, o) { o = $(o); //记录原始索引位置 if (o.attr('idx') === undefined) o.attr('idx', k); //按商品名过滤 if ((typeof(filterPName) === 'function' && !filterPName(getProductName(o), priceInfo.pageCat, priceInfo.pageCatId)) || (priceInfo.regexp && !priceInfo.regexp.test(getProductName(o)))) { --fltRetPName; return false; } //按价格过滤 var price = getPrice(o); if (price.now < priceInfo.min || (0 < priceInfo.max && priceInfo.min <= priceInfo.max && priceInfo.max < price.now)) return false; //标注优惠力度 var priceOff = price.pre - price.now; var discount = price.now / price.pre; var goodsInfo = o.find('.seckill_mod_goods_info'); if (discount <= 0.1) { goodsInfo.attr('title', '1折以下(优惠'+priceOff+')').css('background-color', 'gold'); //1折以下 } else if (discount <= 0.3) { goodsInfo.attr('title', '3折以下(优惠'+priceOff+')').css('background-color', 'springgreen'); //3折以下 } else if (discount <= 0.5) { goodsInfo.attr('title', '5折以下(优惠'+priceOff+')').css('background-color', '#BBFFEE'); //5折以下 } else if (discount <= 0.75) { goodsInfo.attr('title', '75折以下(优惠'+priceOff+')').css('background-color', '#CCEEFF'); //75折以下 } else if (priceOff >= 90) { goodsInfo.attr('title', '优惠超过90('+priceOff+')').css('background-color', '#FFEEEE'); //优惠超过90 } else { goodsInfo.removeAttr('title').css('background-color', ''); } //命中 return true; }); var niceGoods = groups[true]; if (niceGoods && niceGoods.length > 0) { fltRetPrice = niceGoods.length; //排序 niceGoods.sort(function(g1, g2) { return getPrice(g1).now - getPrice(g2).now || //<---------------------------------------如果要降序,修改这里 $(g1).attr('idx') - $(g2).attr('idx'); }); //取消图片延迟加载 forceLoadLazyImgs(niceGoods); //如果上一次过滤结果无符合条件商品,隐藏提示 var noGoods = goodsList.find('#noGoods'); if (noGoods.length == 1) groups[false].push(noGoods[0]); } else { niceGoods = goodsList.find('#noGoods')[0] || $('<center id="noGoods"><h2><br/>该分类下的所有商品都不符合过滤条件。<br/><br/><br/></h2></center'); } //替换原内容 $(niceGoods).css('display', ''); $(groups[false]).css('display', 'none'); $(goods[0].closest('ul')).prepend($(niceGoods).remove()); } return [goods.length, fltRetPName, fltRetPrice]; } //取消图片延迟加载 function forceLoadLazyImgs(elms) { var lazyImgs = $(elms).find('img[data-lazy-img][data-lazy-img!="done"]'); if (lazyImgs.length > 0) lazyImgs.each(function(idx) { var img = $(this); this.src = img.attr('data-lazy-img'); img.removeAttr('data-lazy-img'); }); } //加载/保存页面价格设置 function loadPagePrice(pageKey) { var g_min = GM_getValue('jd_miaosha_price_min'); var g_max = GM_getValue('jd_miaosha_price_max'); if (g_min === undefined) g_min = 0; if (g_max === undefined) g_max = 0; var p_min = GM_getValue(pageKey + '_price_min'); var p_max = GM_getValue(pageKey + '_price_max'); if (p_min === undefined) p_min = 0; if (p_max === undefined) p_max = 0; var checked = GM_getValue(pageKey); var min = checked ? p_min : g_min; var max = checked ? p_max : g_max; var rsrc = GM_getValue(pageKey + '_name_regex_src'); if (rsrc === undefined) rsrc = ''; var rflg = GM_getValue(pageKey + '_name_regex_flg'); if (rflg === undefined) rflg = ''; var re = rsrc.length > 0 ? new RegExp(rsrc, rflg) : undefined; var rs = rflg.length > 0 ? re.toString() : rsrc; var parts = pageKey.split('_'); return { pageKey: pageKey, pageCat: parts[parts.length - 2], pageCatId: parts[parts.length - 1], usePageSetting: checked, min: min, max: max, p_min: p_min, p_max: p_max, g_min: g_min, g_max: g_max, regstr: rs, regexp: re, }; } function saveCurrentPagePrice(oldChecked) { var min = getFloat($('#fltPriceMin').first().val()); var max = getFloat($('#fltPriceMax').first().val()); var keyMin, keyMax; //更新 priceInfo.usePageSetting = $('#fltPriceOne').first().is(':checked'); if (oldChecked === undefined) oldChecked = priceInfo.usePageSetting; if (oldChecked) { priceInfo.p_min = min; priceInfo.p_max = max; keyMin = currentPageKey + '_price_min'; keyMax = currentPageKey + '_price_max'; } else { priceInfo.g_min = min; priceInfo.g_max = max; keyMin = 'jd_miaosha_price_min'; keyMax = 'jd_miaosha_price_max'; } if (priceInfo.usePageSetting) { priceInfo.min = priceInfo.p_min; priceInfo.max = priceInfo.p_max; } else { priceInfo.min = priceInfo.g_min; priceInfo.max = priceInfo.g_max; } priceInfo.regstr = $('#fltNameRegx').first().val().trim(); if (priceInfo.regstr.length > 0) { var r = /^\/(.*)\/([igm]{0,3})$/.exec(priceInfo.regstr); priceInfo.regexp = r ? new RegExp(r[1], r[2]) : new RegExp(priceInfo.regstr); } else priceInfo.regexp = undefined; //保存 if (min === 0) GM_deleteValue(keyMin); else GM_setValue(keyMin, min); if (max === 0) GM_deleteValue(keyMax); else GM_setValue(keyMax, max); if (priceInfo.usePageSetting || priceInfo.p_min > 0 || priceInfo.p_max > 0) GM_setValue(currentPageKey, priceInfo.usePageSetting); else GM_deleteValue(currentPageKey); var regexKey = currentPageKey + '_name_regex'; if (priceInfo.regexp) { var src = priceInfo.regexp.source; if (src.length > 0 && src !== '(?:)') GM_setValue(regexKey + '_src', priceInfo.regexp.source); else GM_deleteValue(regexKey + '_src'); var flg = priceInfo.regexp.flags; if (flg.length > 0) GM_setValue(regexKey + '_flg', flg); else GM_deleteValue(regexKey + '_flg'); } else { GM_deleteValue(regexKey + '_src'); GM_deleteValue(regexKey + '_flg'); } } //获取商品名 function getProductName(elm) { return $(elm).find('.seckill_mod_goods_title').first().text().trim(); } //获取商品价格 function getPrice(elm) { return { now: getFloat($(elm).find('.seckill_mod_goods_price_now').first().text()), pre: getFloat($(elm).find('.seckill_mod_goods_price_pre').first().text()) }; } //字串转浮点数 function getFloat(str) { str = str.replace('¥','').replace('¥','').trim(); if (!/^-?(\d+|\d+\.\d+|\.\d+)([eE][-+]?\d+)?$/.test(str)) return 0; //非浮点数字串 return parseFloat(str); } })(); function groupObjs(objs, callback) { if (objs instanceof jQuery) objs = $.makeArray(objs); var ret = {}; for(var i=0; i<objs.length; ++i) { var obj = objs[i]; var key = callback(i, obj); if(!(key in ret)) ret[key] = []; ret[key].push(obj); } return ret; }