└── music163
├── manifest.json
├── package.json
├── .gitignore
├── index.js
├── popup.html
├── prd
└── index.js
├── music163order.js
├── webpack.config.js
└── quicksort.js
/music163/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "music.163.com歌单排序",
3 | "version": "0.9.0",
4 | "manifest_version": 2,
5 |
6 | "description": "PC浏览器打开 music.163.com 页面,执行脚本即可获取排序数据",
7 | "browser_action": {
8 | "default_title": "music163sort",
9 | "default_popup": "popup.html"
10 | },
11 | "permissions": [
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/music163/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "music163",
3 | "version": "1.0.0",
4 | "description": "",
5 | "scripts": {
6 | "pk": "webpack"
7 | },
8 | "author": "functions.bin@gmail.com",
9 | "license": "ISC",
10 | "devDependencies": {
11 | "clean-webpack-plugin": "^0.1.12",
12 | "css-loader": "^0.25.0",
13 | "extract-text-webpack-plugin": "^1.0.1",
14 | "webpack": "^1.13.2",
15 | "webpack-md5-hash": "0.0.5"
16 | },
17 | "dependencies": {
18 | "hogan": "^1.0.2",
19 | "jquery": "^3.1.1"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/music163/.gitignore:
--------------------------------------------------------------------------------
1 | /dev/
2 | /refs/
3 |
4 |
5 | # kdiff3 ignore
6 | *.orig
7 |
8 | # maven ignore
9 | target/
10 |
11 | # eclipse ignore
12 | .settings/
13 | .project
14 | .classpath
15 |
16 | # idea ignore
17 | .idea/
18 | *.ipr
19 | *.iml
20 | *.iws
21 |
22 | # temp ignore
23 | *.log
24 | *.cache
25 | *.diff
26 | *.patch
27 | *.tmp
28 |
29 | # system ignore
30 | .DS_Store
31 | Thumbs.db
32 |
33 | # package ignore (optional)
34 | # *.jar
35 | # *.war
36 | # *.zip
37 | # *.tar
38 | # *.tar.gz
39 |
40 |
41 | .sass-cache
42 | /resource/
43 | /log/
44 | /node_modules/
--------------------------------------------------------------------------------
/music163/index.js:
--------------------------------------------------------------------------------
1 | // var $ = require('jquery');
2 | var run = require('./music163order.js');
3 |
4 | run(0, 42, function(list) {
5 | list.forEach(function(item) {
6 | console.log(item.nb + ' ' + item.id + ' ' + item.title);
7 | });
8 | });
9 |
10 | // run(start, end, function(list) {
11 | // console.log(111)
12 | // // $('#js-song-list').html(getSongListHTML(list));
13 | // });
14 |
15 | // function getSongListHTML (songList) {
16 | // var htmlArr = [];
17 | // songList.forEach(function(item) {
18 | // htmlArr.push(
19 | // `
20 | //
21 | //
22 | //

23 | //
24 | //
25 | //
${item.nb}
26 | //
27 | //
28 | //
29 | // `
30 | // );
31 | // });
32 | // return htmlArr.join('');
33 | // }
--------------------------------------------------------------------------------
/music163/popup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Music163sort
8 |
9 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/music163/prd/index.js:
--------------------------------------------------------------------------------
1 | !function(n){function e(o){if(t[o])return t[o].exports;var r=t[o]={exports:{},id:o,loaded:!1};return n[o].call(r.exports,r,r.exports,e),r.loaded=!0,r.exports}var t={};return e.m=n,e.c=t,e.p="",e(0)}([function(n,e,t){var o=t(1);o(0,42,function(n){n.forEach(function(n){console.log(n.nb+" "+n.id+" "+n.title)})})},function(n,e,t){function o(){var n=null,e=document.querySelector("#g_iframe").contentWindow.document.querySelectorAll("#m-pl-container li");console.log(l+"========="),e.forEach(function(e){n={id:e.querySelector(".msk").href,nb:+e.querySelector(".nb").innerText.replace("万","0000"),title:e.innerText},a.push(n)})}function r(n){if(l>f){var e=u(a,"desc","nb");return void n(e)}document.querySelector("#g_iframe").contentWindow.document.querySelector(".zbtn.znxt").click(),setTimeout(function(){c(function(){console.log(l),o(),l++,r(n)})},300)}function c(n){setTimeout(function(){var e=document.querySelector("#g_iframe").contentWindow.document.querySelector("#m-pl-pager");e?n():c(n)},200)}var u=t(2),i=-1,f=-1,l=-1,a=null;n.exports=function(n,e,t){i=n,f=e,l=i,a=[],r(t)}},function(n,e){n.exports=function(n,e,t){function o(n,e,t){var o=n[e];n[e]=n[t],n[t]=o}function r(n,e,t){for(var r=e,c=n[t],u=e;uc&&(o(n,r,u),r++);return o(n,t,r),r}function u(n,e,r){for(var c=e,u=n[r][t],i=e;iu&&(o(n,c,i),c++);return o(n,r,c),c}function f(n,o,l){if(!(o>l)){var a;a=t?"desc"===e?i(n,o,l):u(n,o,l):"desc"===e?c(n,o,l):r(n,o,l),f(n,o,a-1),f(n,a+1,l)}}return f(n,0,n.length-1),n}}]);
--------------------------------------------------------------------------------
/music163/music163order.js:
--------------------------------------------------------------------------------
1 | // 引入排序方法
2 | var quickOrder = require('./quicksort.js');
3 |
4 | // 私有变量
5 | var _start = -1;
6 | var _end = -1;
7 | var curPage = -1;
8 | var allList = null;
9 |
10 | // 获取当前页的歌单列表,并收集每个歌单的信息
11 | function getCurPageList() {
12 | var songItem = null;
13 | var songList = document.querySelector('#g_iframe')
14 | .contentWindow.document.querySelectorAll('#m-pl-container li');
15 | console.log(curPage + '=========');
16 | songList.forEach(function(item){
17 | songItem = {
18 | id: item.querySelector('.msk').href,
19 | nb: +item.querySelector('.nb').innerText.replace('万', '0000'),
20 | title: item.innerText
21 | };
22 | allList.push(songItem);
23 | });
24 | }
25 |
26 | // 翻页并获取每页列表中的所有歌单详情
27 | function switchPage(cb) {
28 | if(curPage > _end) {
29 | // 对收集的结果进行排序
30 | var orderArr = quickOrder(allList, 'desc', 'nb');
31 | cb(orderArr);
32 | return;
33 | }
34 | document.querySelector('#g_iframe').contentWindow.document.querySelector('.zbtn.znxt').click();
35 | setTimeout(function() {
36 | isLoaded(function(){
37 | console.log(curPage);
38 | getCurPageList();
39 | curPage++;
40 | switchPage(cb);
41 | });
42 | }, 300)
43 | }
44 |
45 | // 判断列表区域是否加载完成
46 | function isLoaded(cb) {
47 | setTimeout(function(){
48 | var pager = document.querySelector('#g_iframe').contentWindow.document.querySelector('#m-pl-pager');
49 | if(pager){
50 | cb();
51 | } else {
52 | isLoaded(cb);
53 | }
54 | }, 200);
55 | }
56 |
57 |
58 | module.exports = function(start, end, cb) {
59 | _start = start;
60 | _end = end;
61 | curPage = _start;
62 | allList = [];
63 | switchPage(cb);
64 | }
--------------------------------------------------------------------------------
/music163/webpack.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * configuration description
3 | * https://github.com/webpack/docs/wiki/configuration#configuration-object-content
4 | * webpack document
5 | * http://webpack.github.io/docs/
6 | */
7 | 'use strict'
8 | var path = require('path');
9 | var webpack = require('webpack');
10 | var ProgressPlugin = require('webpack/lib/ProgressPlugin');
11 | var CleanWebpackPlugin = require('clean-webpack-plugin');
12 | var WebpackMd5Hash = require('webpack-md5-hash');
13 |
14 | //提取css独立成文件
15 | var ExtractTextPlugin = require("extract-text-webpack-plugin");
16 | var extractSCSS = new ExtractTextPlugin('[name]@[chunkhash].css');
17 |
18 |
19 | module.exports = {
20 | //获取项目入口js文件
21 | entry: {
22 | "index": "./index.js"
23 | },
24 | output: {
25 | //文件输出目录
26 | path: path.join(__dirname, 'prd'),
27 | //根据入口文件输出的对应多个文件名
28 | filename: '[name].js'
29 | },
30 | resolve: {
31 | extensions: ['', '.js', '.css']
32 | },
33 | //各种加载器,即让各种文件格式可用require引用
34 | module: {
35 | loaders: [
36 | {
37 | test: /\.css$/,
38 | include: /src\/styles\//,
39 | loader: extractSCSS.extract('css-loader?sourceMap&minimize')
40 | }
41 | ]
42 | },
43 | plugins: [
44 | // 清空编译后的目录
45 | new CleanWebpackPlugin(['prd']),
46 | extractSCSS,
47 | //js文件的压缩
48 | new webpack.optimize.UglifyJsPlugin({
49 | compress: {
50 | warnings: false
51 | }
52 | }),
53 | // 根据文件内容生成 MD5
54 | // new WebpackMd5Hash(),
55 | new ProgressPlugin(function(percentage, msg) {
56 | console.log(parseInt(percentage * 100) + '%', msg);
57 | })
58 | ]
59 | };
--------------------------------------------------------------------------------
/music163/quicksort.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 快速排序算法
3 | * @param {[type]} array 要排序的数组; 可以是对象数组,但必须指定第三个参数;
4 | * @param {[type]} sortType 排序类型: 'asc' 默认从小到大排序; 'desc' 从大到小排序;
5 | * @param {[type]} objectKey 如果 array 参数是对象数组,需要根据指定字段进行排序,该字段必须是数值类型;
6 | * @return {[type]} 排序后的数组
7 | */
8 | module.exports = function quickSort(array, sortType, objectKey) {
9 |
10 | // 交换元素位置
11 | function swap(array, i, k) {
12 | var temp = array[i];
13 | array[i] = array[k];
14 | array[k] = temp;
15 | }
16 |
17 | // 数组分区,左小右大
18 | function partition(array, left, right) {
19 | var storeIndex = left;
20 | var pivot = array[right]; // 直接选最右边的元素为基准元素
21 | for (var i = left; i < right; i++) {
22 | if (array[i] < pivot) {
23 | swap(array, storeIndex, i);
24 | storeIndex++; // 交换位置后,storeIndex 自增 1,代表下一个可能要交换的位置
25 | }
26 | }
27 | swap(array, right, storeIndex); // 将基准元素放置到最后的正确位置上
28 | return storeIndex;
29 | }
30 |
31 | // 数组分区,左大右小
32 | function partition2(array, left, right) {
33 | var storeIndex = left;
34 | var pivot = array[right]; // 直接选最右边的元素为基准元素
35 | for (var i = left; i < right; i++) {
36 | if (array[i] > pivot) {
37 | swap(array, storeIndex, i);
38 | storeIndex++; // 交换位置后,storeIndex 自增 1,代表下一个可能要交换的位置
39 | }
40 | }
41 | swap(array, right, storeIndex); // 将基准元素放置到最后的正确位置上
42 | return storeIndex;
43 | }
44 |
45 | // 对象数组分区,左小右大
46 | function partitionArrObj(array, left, right) {
47 | var storeIndex = left;
48 | var pivot = array[right][objectKey]; // 直接选最右边的元素为基准元素
49 | for (var i = left; i < right; i++) {
50 | if (array[i][objectKey] < pivot) {
51 | swap(array, storeIndex, i);
52 | storeIndex++; // 交换位置后,storeIndex 自增 1,代表下一个可能要交换的位置
53 | }
54 | }
55 | swap(array, right, storeIndex); // 将基准元素放置到最后的正确位置上
56 | return storeIndex;
57 | }
58 |
59 | // 对象数组分区,左大右小
60 | function partitionArrObj2(array, left, right) {
61 | var storeIndex = left;
62 | var pivot = array[right][objectKey]; // 直接选最右边的元素为基准元素
63 | for (var i = left; i < right; i++) {
64 | if (array[i][objectKey] > pivot) {
65 | swap(array, storeIndex, i);
66 | storeIndex++; // 交换位置后,storeIndex 自增 1,代表下一个可能要交换的位置
67 | }
68 | }
69 | swap(array, right, storeIndex); // 将基准元素放置到最后的正确位置上
70 | return storeIndex;
71 | }
72 |
73 | // 对数组进行分区,对分区后的区域再次分区,递归执行,直到左边起始点索引大于右边起始点索引;
74 | function sort(array, left, right) {
75 | if (left > right) {
76 | return;
77 | }
78 | var storeIndex;
79 | // 如果是对象数组,需要指定用来排序的字段名称
80 | if (objectKey) {
81 | if (sortType === 'desc') {
82 | storeIndex = partitionArrObj2(array, left, right);
83 | } else {
84 | storeIndex = partitionArrObj(array, left, right);
85 | }
86 | } else { // 数值数组
87 | if (sortType === 'desc') {
88 | storeIndex = partition2(array, left, right);
89 | } else {
90 | storeIndex = partition(array, left, right);
91 | }
92 | }
93 | sort(array, left, storeIndex - 1);
94 | sort(array, storeIndex + 1, right);
95 | }
96 | // 开始排序
97 | sort(array, 0, array.length - 1);
98 | // 返回结果
99 | return array;
100 | }
--------------------------------------------------------------------------------