ネイティブ JS はテーブルのソートを実装します
私は最近 JS でのテーブル ソートを学んでいましたが、目立たないテーブル ソートが実際に多くの JS の知識を暗示しているとは思いませんでした。この学習プロセスをここに記録します。皆さんにも役立つことを願っています。
完全なテーブルソートには、次の知識ポイントが含まれます:
を使用した呼び出しメソッド
sortメソッドの詳細
データバインディング
DOMマッピング
以下は、これらの詳細な知識をまとめたものです。最後にこれらの知識ポイントを組み合わせて、次のテーブルの並べ替えケースを実装します。
完全なケースソースコード: https://github.com/daweihe/JS...
1. 知識ポイントのまとめ
1. callメソッドの機能は次のとおりです。これが指すメソッドを変更します。
call このメソッドは Function.prototype
で定義されています。私たちが定義する関数はすべて、Function
クラスのインスタンスと見なすことができます。次に、インスタンスの __proto__
属性を通じてクラスのプロトタイプを見つけることができます。どの関数でも call
や apply
などのメソッドを呼び出すことができます。
まず例を見てみましょう: Function.prototype
的方法。我们定义的任何一个函数都可以认为它是Function
这个类的一个实例。那么就可以通过实例的__proto__
属性找到所属类的原型。任何一个函数都可以调用call
和apply
等方法。
先来看一个例子:
var obj = { name : 'JS' } function testCall () { console.log(this); } testCall.call( obj ); // {name: "JS"}
首先函数testCall
通过原型链查找机制找到call方法执行,call方法在执行过程中把调用call方法这个函数实例中的this都改变成call的第一个参数,接下来调用call方法的这个实例函数执行。
看两个题目:
function fn1() { console.log(1); console.log(this); } function fn2() { console.log(2); console.log(this); } fn1.call(fn2); //this -> fn2 fn1.call.call(fn2); //这里的call是改变function.__proto__.call的call方法中的this,相当于执行参数
call方法在执行的时候,call方法的第一个参数是用来改变this的,而从第二个参数开始都是传给调用call的函数的参数。
在非严格模式下,给call方法不传递参数、或者传递null、undefined后,this都是指向window
。
sum.call(); //window sum.call(null); //window sum.call(undefined); //window
严格模式下call执行的时候和非严格模式不同:
sum.call(); //undefined sum.call(null); //null sum.call(undefined); //undefined
下面使用call方法实现一个类数组转换为数组的方法:
function listToArray (likeAry) { var ary = []; try { ary = Array.prototype.slice.call(likeAry); } catch (e) { for (var i = 0; i < likeAry.length; i ++) { ary[ary.length] = likeAry[i]; } } return ary; }
和call类似的方法还有apply和bind方法,这里简单总结一下。
apply方法的作用和call方法一模一样,只是传参的形式不太一样,apply将函数的参数用数组包裹起来:
function sum(num1, num2) { console.log(num2 + num1); console.log(this); } sum.apply(null,[100,200]);
bind方法同样也是用来改变this关键字的,但是它只是仅仅改变this指向,不立即执行调用this的函数。
function sum(num1, num2) { console.log(num2 + num1); console.log(this); } var obj = {name : 'zx'} var temp = sum.bind(obj); //temp已经是被改变了this的函数 temp(100,200); //当我们需要的时候才执行 //或者像这样处理 var temp = sum.bind(null, 100, 200); temp();
bind方法体现了js中的预处理思想。
2、 sort排序深入
我们知道数组的sort
方法只能排序10以内的数组。如果需要排序的数组中存在大于10的数字,我们就需要向sort
方法中传入回调函数,常见的是这样:
ary.sort(function (a,b) { return a - b; });
这样就能实现数组的升序排序。那么这样排序的原理到底是什么呢?
对于传入的两个参数:a
代表的是找到的数组中的当前项,b
代表的是当前项的后一项。
return a -b
: 如果a大于b,返回结果,a与b交换位置。如果a小于b,那么a和b位置不变。 这是升序排序return b -a
: 如果b大于a,返回结果,a与b交换位置。如果a小于b,那么a和b位置不变。 这是降序排序
了解了基本原理后,对于这样一个二维数组,如何实现按年龄排序?
var persons = [{ name:'dawei', age:55 },{ name:'ahung', age:3 },{ name:'maomi', age:2 },{ name:'heizi', age:78 },{ name:'afu', age:32 }];
其实很简单:
ary.sort(function(a,b){ return a.age - b.age; });
如果按姓名排序,则要涉及字符串的localeCompare()
方法:
ary.sort(function(a,b){ return a.name.localeCompare(b.name); });
name.localeCompare()
这个方法会根据两个字符串的字母进行比较,如果前一个字符串的第一个字母在24个英文字母中出现的位置比后一个字符串的第一个字符出现的位置靠前,则认定第一个字符串小,返回-1
//ary为需要添加到页面中的数据数组 var op = document.getElementById("box");//获取容器 var myUl = op.getElementsByTagName("ul")[0];//获取列表 var arrLength = ary.length; for (var i = 0;i < arrLength ; i ++) { //动态创建元素 var oli = document.createElement("li"); oli.innerHTML = '<span>' + (i + 5) + '</span>' + ary[i].title; myUl.appendChild(oli);//动态添加元素 }
testCall
は、実行プロセス中に、プロトタイプ チェーン検索メカニズムを通じて実行する呼び出しメソッドを見つけます。呼び出しメソッドは、関数内でこれを変更します。 call メソッドを呼び出すインスタンス その後、call の最初のパラメータが呼び出されて、call メソッドのインスタンス関数が実行されます。 2 つの質問を見てください: var str = "";
for(var i=0; i<ary.length; i++){
str += '<li>';
str += '<span>';
str += (i+5);
str += '</span>';
str += ary[i].title;
str += '</li>';
}
myUl.innerHTML += str;
ログイン後にコピーログイン後にコピー
call メソッドが実行されるとき、call メソッドの最初のパラメータはこれを変更するために使用され、2 番目のパラメータから開始して、呼び出しを呼び出す関数に渡されるパラメータです。 非厳密モードでは、呼び出しメソッドにパラメータが渡されない場合、または null または未定義が渡された場合、これは var str = ""; for(var i=0; i<ary.length; i++){ str += '<li>'; str += '<span>'; str += (i+5); str += '</span>'; str += ary[i].title; str += '</li>'; } myUl.innerHTML += str;
window
を指します。
var frg = document.createDocumentFragment();//创建文档碎片 for (var i =0; i <ary.length ;i ++ ){ var li = document.createElement("li"); li.innerHTML = '<span>' + ( i + 5 ) + '</span>' + ary[i].title; frg.appendChild(li);//将数据动态添加至文档碎片中 } myUl.appendChild(frg); //将数据一次性添加到页面中 frg = null; //释放内存
<ul id="myul"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul>
var myul = document.getElementById("myul"); var mylis = myul.getElementsByTagName('li'); for (var i = mylis.length - 1 ; i >= 0; i --) { myul.appendChild(mylis[i]); } console.log(mylis.length); // 5
<ul id="myul"> <li>5</li> <li>4</li> <li>3</li> <li>2</li> <li>1</li> </ul>
var res = ''; //声明一个全局变量,接收数据 var xhr = new XMLHttpRequest(); xhr.open('get', 'date.txt', false); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { res = JSON.parse(xhr.responseText); } } xhr.send(null);
sort
メソッドは 10 個以内の配列のみを並べ替えることができることがわかっています。並べ替える必要がある配列内に 10 より大きい数値がある場合、コールバック関数を sort
メソッドに渡す必要があります。一般的な関数は次のとおりです。 🎜var frg = document.createDocumentFragment(); for (let i = 0; i < res.length; i++) { var tr = document.createElement("tr"); for (key in res[i]) { var td = document.createElement("td"); td.innerHTML = res[i][key]; tr.appendChild(td); } frg.appendChild(tr); } tbody.appendChild(frg);
a
は見つかった配列内の現在の項目を表し、b
は現在の項目の後の項目を表します。 🎜🎜🎜🎜return a -b
: a が b より大きい場合、結果を返し、a と b の位置を交換します。 a が b より小さい場合、a と b の位置は変更されません。 これは昇順です🎜🎜🎜🎜return b -a
: b が a より大きい場合、結果を返し、a と b の位置を交換します。 a が b より小さい場合、a と b の位置は変更されません。 これは降順です🎜🎜🎜🎜基本原理を理解した後、このような2次元配列の場合、年齢でソートするにはどうすればよいでしょうか? 🎜//为两列添加点击事件 for (let i = 0; i < ths.length; i++) { let curTh = ths[i]; curTh.sortFlag = -1; //用于对列进行升降序排列 curTh.index = i; //记录当前点击列的索引,便于排序操作 if (curTh.className == 'sort') { curTh.onclick = function() { sort.call(this); //改变排序函数内this的指向,让其指向当前点击列 } } } //排序方法 function sort() { //对数组元素进行排序 let target = this; //这里将this取出,因为在sort方法里需要使用该this,但是sort方法里的this是调用方法的数组 this.sortFlag *= -1; //1 代表升序 -1代表降序 let ary = listToArray(bodyTrs); //获取body数据 ary = ary.sort(function(a, b) { let one = a.cells[target.index].innerHTML; let two = b.cells[target.index].innerHTML; let oneNum = parseFloat(one); let twoNum = parseFloat(two); if (isNaN(oneNum) || isNaN(two)) { return one.localeCompare(two) * target.sortFlag; } else { return (oneNum - twoNum) * target.sortFlag; } }); //把排好序的数组重新写入页面 let frg = document.createDocumentFragment(); for (let i = 0; i < ary.length; i++) { rg.appendChild(ary[i]); } tbody.appendChild(frg); frg = null; //点击某列时,要将其他列的排序标志恢复为-1,让下次再点击任意一个标签时都是默认是升序排列 for (let i = 0; i < ths.length; i++) { if (ths[i] != this) { ths[i].sortFlag = -1; } } }
var obj = { name : 'JS' } function testCall () { console.log(this); } testCall.call( obj ); // {name: "JS"}
localeCompare()
メソッドが関係します: 🎜function fn1() { console.log(1); console.log(this); } function fn2() { console.log(2); console.log(this); } fn1.call(fn2); //this -> fn2 fn1.call.call(fn2); //这里的call是改变function.__proto__.call的call方法中的this,相当于执行参数
name.localeCompare()
このメソッドの比較は、24 個の英語文字のうち、前の文字列の最初の文字が後の文字列の最初の文字よりも前に出現する場合、最初の文字が最初に考慮されます。小さい場合は、-1
が返されます。後で出現する場合は、最初の文字列の方が大きいとみなされ、1 が返されます。比較された文字が等しい場合。次に、次の文字を比較します。 🎜🎜この方法は非常に実用的で、漢字の場合、比較のために中国語の文字を中国語のピンインに自動的に変換するためによく使用されます。 🎜🎜3. データバインディング🎜🎜 js では、データバインディングを実装するために、通常、動的バインディングまたは文字列スプライシングが使用されます。 🎜🎜動的バインディング: 🎜sum.call(); //window sum.call(null); //window sum.call(undefined); //window
sum.call(); //undefined sum.call(null); //null sum.call(undefined); //undefined
function listToArray (likeAry) { var ary = []; try { ary = Array.prototype.slice.call(likeAry); } catch (e) { for (var i = 0; i < likeAry.length; i ++) { ary[ary.length] = likeAry[i]; } } return ary; }
4、DOM映射
DOM映射机制:所谓映射,就是指两个元素集之间元素相互“对应”的关系。页面中的标签集合和在JS中获取到的元素对象(元素集合)就是这样的关系。如果页面中的HTML标签结构发送变化,那么集合中对应的内容也会跟着自动改变。
<ul id="myul"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul>
对于这样一个列表使用下列脚本:
var myul = document.getElementById("myul"); var mylis = myul.getElementsByTagName('li'); for (var i = mylis.length - 1 ; i >= 0; i --) { myul.appendChild(mylis[i]); } console.log(mylis.length); // 5
将获取到的列表元素反序重新插入ul中,那么ul列表会变成下面这样:
<ul id="myul"> <li>5</li> <li>4</li> <li>3</li> <li>2</li> <li>1</li> </ul>
我们看到列表的长度依然是5,只是位置颠倒了。这是因为每个li标签和JS中获取的标签对象存在一个对应关系,当某个标签被重新插入到页面中时,页面中对应的标签会移动到插入的位置。这就是DOM映射。
二、实现表格排序
1、使用ajax获取数据
之所以使用动态获取数据,是为了使用文档碎片绑定数据。
var res = ''; //声明一个全局变量,接收数据 var xhr = new XMLHttpRequest(); xhr.open('get', 'date.txt', false); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { res = JSON.parse(xhr.responseText); } } xhr.send(null);
此时数据就保存在了res
这个全局变量之中。
2、使用文档碎片绑定数据
var frg = document.createDocumentFragment(); for (let i = 0; i < res.length; i++) { var tr = document.createElement("tr"); for (key in res[i]) { var td = document.createElement("td"); td.innerHTML = res[i][key]; tr.appendChild(td); } frg.appendChild(tr); } tbody.appendChild(frg);
3、对表格进行排序
这里涉及的点较多
//为两列添加点击事件 for (let i = 0; i < ths.length; i++) { let curTh = ths[i]; curTh.sortFlag = -1; //用于对列进行升降序排列 curTh.index = i; //记录当前点击列的索引,便于排序操作 if (curTh.className == 'sort') { curTh.onclick = function() { sort.call(this); //改变排序函数内this的指向,让其指向当前点击列 } } } //排序方法 function sort() { //对数组元素进行排序 let target = this; //这里将this取出,因为在sort方法里需要使用该this,但是sort方法里的this是调用方法的数组 this.sortFlag *= -1; //1 代表升序 -1代表降序 let ary = listToArray(bodyTrs); //获取body数据 ary = ary.sort(function(a, b) { let one = a.cells[target.index].innerHTML; let two = b.cells[target.index].innerHTML; let oneNum = parseFloat(one); let twoNum = parseFloat(two); if (isNaN(oneNum) || isNaN(two)) { return one.localeCompare(two) * target.sortFlag; } else { return (oneNum - twoNum) * target.sortFlag; } }); //把排好序的数组重新写入页面 let frg = document.createDocumentFragment(); for (let i = 0; i < ary.length; i++) { rg.appendChild(ary[i]); } tbody.appendChild(frg); frg = null; //点击某列时,要将其他列的排序标志恢复为-1,让下次再点击任意一个标签时都是默认是升序排列 for (let i = 0; i < ths.length; i++) { if (ths[i] != this) { ths[i].sortFlag = -1; } } }
表格排序应用很常见,在面试中也会有这样的题目。这个小案例做下来,受益匪浅。这是我在学习的某峰学院的JS课程中的一个案例,如果对JS掌握不扎实的同学,欢迎保存:链接: https://pan.baidu.com/s/1jHVy8Uq 密码: v4jk
。如果链接失效,加Q群领取:154658901
。
私は最近 JS でのテーブル ソートを学んでいましたが、目立たないテーブル ソートが実際に多くの JS の知識を暗示しているとは思いませんでした。この学習プロセスをここに記録します。皆さんにも役立つことを願っています。
完全なテーブルソートには、次の知識ポイントが含まれます:
を使用した呼び出しメソッド
sortメソッドの詳細
データバインディング
DOMマッピング
以下は、これらの詳細な知識をまとめたものです。最後にこれらの知識ポイントを組み合わせて、次のテーブルの並べ替えケースを実装します。
完全なケースソースコード: https://github.com/daweihe/JS...
1. 知識ポイントのまとめ
1. callメソッドの機能は次のとおりです。これが指すメソッドを変更します。
call このメソッドは Function.prototype
で定義されています。私たちが定義する関数はすべて、Function
クラスのインスタンスと見なすことができます。次に、インスタンスの __proto__
属性を通じてクラスのプロトタイプを見つけることができます。どの関数でも call
や apply
などのメソッドを呼び出すことができます。
まず例を見てみましょう: Function.prototype
的方法。我们定义的任何一个函数都可以认为它是Function
这个类的一个实例。那么就可以通过实例的__proto__
属性找到所属类的原型。任何一个函数都可以调用call
和apply
等方法。
先来看一个例子:
var obj = { name : 'JS' } function testCall () { console.log(this); } testCall.call( obj ); // {name: "JS"}
首先函数testCall
通过原型链查找机制找到call方法执行,call方法在执行过程中把调用call方法这个函数实例中的this都改变成call的第一个参数,接下来调用call方法的这个实例函数执行。
看两个题目:
function fn1() { console.log(1); console.log(this); } function fn2() { console.log(2); console.log(this); } fn1.call(fn2); //this -> fn2 fn1.call.call(fn2); //这里的call是改变function.__proto__.call的call方法中的this,相当于执行参数
call方法在执行的时候,call方法的第一个参数是用来改变this的,而从第二个参数开始都是传给调用call的函数的参数。
在非严格模式下,给call方法不传递参数、或者传递null、undefined后,this都是指向window
。
sum.call(); //window sum.call(null); //window sum.call(undefined); //window
严格模式下call执行的时候和非严格模式不同:
sum.call(); //undefined sum.call(null); //null sum.call(undefined); //undefined
下面使用call方法实现一个类数组转换为数组的方法:
function listToArray (likeAry) { var ary = []; try { ary = Array.prototype.slice.call(likeAry); } catch (e) { for (var i = 0; i < likeAry.length; i ++) { ary[ary.length] = likeAry[i]; } } return ary; }
和call类似的方法还有apply和bind方法,这里简单总结一下。
apply方法的作用和call方法一模一样,只是传参的形式不太一样,apply将函数的参数用数组包裹起来:
function sum(num1, num2) { console.log(num2 + num1); console.log(this); } sum.apply(null,[100,200]);
bind方法同样也是用来改变this关键字的,但是它只是仅仅改变this指向,不立即执行调用this的函数。
function sum(num1, num2) { console.log(num2 + num1); console.log(this); } var obj = {name : 'zx'} var temp = sum.bind(obj); //temp已经是被改变了this的函数 temp(100,200); //当我们需要的时候才执行 //或者像这样处理 var temp = sum.bind(null, 100, 200); temp();
bind方法体现了js中的预处理思想。
2、 sort排序深入
我们知道数组的sort
方法只能排序10以内的数组。如果需要排序的数组中存在大于10的数字,我们就需要向sort
方法中传入回调函数,常见的是这样:
ary.sort(function (a,b) { return a - b; });
这样就能实现数组的升序排序。那么这样排序的原理到底是什么呢?
对于传入的两个参数:a
代表的是找到的数组中的当前项,b
代表的是当前项的后一项。
return a -b
: 如果a大于b,返回结果,a与b交换位置。如果a小于b,那么a和b位置不变。 这是升序排序return b -a
: 如果b大于a,返回结果,a与b交换位置。如果a小于b,那么a和b位置不变。 这是降序排序
了解了基本原理后,对于这样一个二维数组,如何实现按年龄排序?
var persons = [{ name:'dawei', age:55 },{ name:'ahung', age:3 },{ name:'maomi', age:2 },{ name:'heizi', age:78 },{ name:'afu', age:32 }];
其实很简单:
ary.sort(function(a,b){ return a.age - b.age; });
如果按姓名排序,则要涉及字符串的localeCompare()
方法:
ary.sort(function(a,b){ return a.name.localeCompare(b.name); });
name.localeCompare()
这个方法会根据两个字符串的字母进行比较,如果前一个字符串的第一个字母在24个英文字母中出现的位置比后一个字符串的第一个字符出现的位置靠前,则认定第一个字符串小,返回-1
//ary为需要添加到页面中的数据数组 var op = document.getElementById("box");//获取容器 var myUl = op.getElementsByTagName("ul")[0];//获取列表 var arrLength = ary.length; for (var i = 0;i < arrLength ; i ++) { //动态创建元素 var oli = document.createElement("li"); oli.innerHTML = '<span>' + (i + 5) + '</span>' + ary[i].title; myUl.appendChild(oli);//动态添加元素 }
testCall
は、実行プロセス中に、プロトタイプ チェーン検索メカニズムを通じて実行する呼び出しメソッドを見つけます。呼び出しメソッドは、関数内でこれを変更します。 call メソッドを呼び出すインスタンス その後、call の最初のパラメータが呼び出されて、call メソッドのインスタンス関数が実行されます。 2 つの質問を見てください: var str = "";
for(var i=0; i<ary.length; i++){
str += '<li>';
str += '<span>';
str += (i+5);
str += '</span>';
str += ary[i].title;
str += '</li>';
}
myUl.innerHTML += str;
ログイン後にコピーログイン後にコピー
call メソッドが実行されるとき、call メソッドの最初のパラメータはこれを変更するために使用され、2 番目のパラメータから開始して、呼び出しを呼び出す関数に渡されるパラメータです。 非厳密モードでは、呼び出しメソッドにパラメータが渡されない場合、または null または未定義が渡された場合、これは var str = ""; for(var i=0; i<ary.length; i++){ str += '<li>'; str += '<span>'; str += (i+5); str += '</span>'; str += ary[i].title; str += '</li>'; } myUl.innerHTML += str;
window
を指します。
var frg = document.createDocumentFragment();//创建文档碎片 for (var i =0; i <ary.length ;i ++ ){ var li = document.createElement("li"); li.innerHTML = '<span>' + ( i + 5 ) + '</span>' + ary[i].title; frg.appendChild(li);//将数据动态添加至文档碎片中 } myUl.appendChild(frg); //将数据一次性添加到页面中 frg = null; //释放内存
<ul id="myul"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul>
var myul = document.getElementById("myul"); var mylis = myul.getElementsByTagName('li'); for (var i = mylis.length - 1 ; i >= 0; i --) { myul.appendChild(mylis[i]); } console.log(mylis.length); // 5
<ul id="myul"> <li>5</li> <li>4</li> <li>3</li> <li>2</li> <li>1</li> </ul>
var res = ''; //声明一个全局变量,接收数据 var xhr = new XMLHttpRequest(); xhr.open('get', 'date.txt', false); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { res = JSON.parse(xhr.responseText); } } xhr.send(null);
sort
メソッドは 10 個以内の配列のみを並べ替えることができることがわかっています。並べ替える必要がある配列内に 10 より大きい数値がある場合、コールバック関数を sort
メソッドに渡す必要があります。一般的な関数は次のとおりです。 🎜var frg = document.createDocumentFragment(); for (let i = 0; i < res.length; i++) { var tr = document.createElement("tr"); for (key in res[i]) { var td = document.createElement("td"); td.innerHTML = res[i][key]; tr.appendChild(td); } frg.appendChild(tr); } tbody.appendChild(frg);
a
は見つかった配列内の現在の項目を表し、b
は現在の項目の後の項目を表します。 🎜🎜🎜🎜return a -b
: a が b より大きい場合、結果を返し、a と b の位置を交換します。 a が b より小さい場合、a と b の位置は変更されません。 これは昇順です🎜🎜🎜🎜return b -a
: b が a より大きい場合、結果を返し、a と b の位置を交換します。 a が b より小さい場合、a と b の位置は変更されません。 これは降順です🎜🎜🎜🎜基本原理を理解した後、このような2次元配列の場合、年齢でソートするにはどうすればよいでしょうか? 🎜//为两列添加点击事件 for (let i = 0; i < ths.length; i++) { let curTh = ths[i]; curTh.sortFlag = -1; //用于对列进行升降序排列 curTh.index = i; //记录当前点击列的索引,便于排序操作 if (curTh.className == 'sort') { curTh.onclick = function() { sort.call(this); //改变排序函数内this的指向,让其指向当前点击列 } } } //排序方法 function sort() { //对数组元素进行排序 let target = this; //这里将this取出,因为在sort方法里需要使用该this,但是sort方法里的this是调用方法的数组 this.sortFlag *= -1; //1 代表升序 -1代表降序 let ary = listToArray(bodyTrs); //获取body数据 ary = ary.sort(function(a, b) { let one = a.cells[target.index].innerHTML; let two = b.cells[target.index].innerHTML; let oneNum = parseFloat(one); let twoNum = parseFloat(two); if (isNaN(oneNum) || isNaN(two)) { return one.localeCompare(two) * target.sortFlag; } else { return (oneNum - twoNum) * target.sortFlag; } }); //把排好序的数组重新写入页面 let frg = document.createDocumentFragment(); for (let i = 0; i < ary.length; i++) { rg.appendChild(ary[i]); } tbody.appendChild(frg); frg = null; //点击某列时,要将其他列的排序标志恢复为-1,让下次再点击任意一个标签时都是默认是升序排列 for (let i = 0; i < ths.length; i++) { if (ths[i] != this) { ths[i].sortFlag = -1; } } }
var obj = { name : 'JS' } function testCall () { console.log(this); } testCall.call( obj ); // {name: "JS"}
localeCompare()
メソッドが関係します: 🎜function fn1() { console.log(1); console.log(this); } function fn2() { console.log(2); console.log(this); } fn1.call(fn2); //this -> fn2 fn1.call.call(fn2); //这里的call是改变function.__proto__.call的call方法中的this,相当于执行参数
name.localeCompare()
このメソッドの比較は、24 個の英語文字のうち、前の文字列の最初の文字が後の文字列の最初の文字よりも前に出現する場合、最初の文字が最初に考慮されます。小さい場合は、-1
が返されます。後で出現する場合は、最初の文字列の方が大きいとみなされ、1 が返されます。比較された文字が等しい場合。次に、次の文字を比較します。 🎜🎜この方法は非常に実用的で、漢字の場合、比較のために中国語の文字を中国語のピンインに自動的に変換するためによく使用されます。 🎜🎜3. データバインディング🎜🎜 js では、データバインディングを実装するために、通常、動的バインディングまたは文字列スプライシングが使用されます。 🎜🎜動的バインディング: 🎜sum.call(); //window sum.call(null); //window sum.call(undefined); //window
sum.call(); //undefined sum.call(null); //null sum.call(undefined); //undefined
function listToArray (likeAry) { var ary = []; try { ary = Array.prototype.slice.call(likeAry); } catch (e) { for (var i = 0; i < likeAry.length; i ++) { ary[ary.length] = likeAry[i]; } } return ary; }
4、DOM映射
DOM映射机制:所谓映射,就是指两个元素集之间元素相互“对应”的关系。页面中的标签集合和在JS中获取到的元素对象(元素集合)就是这样的关系。如果页面中的HTML标签结构发送变化,那么集合中对应的内容也会跟着自动改变。
<ul id="myul"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul>
对于这样一个列表使用下列脚本:
var myul = document.getElementById("myul"); var mylis = myul.getElementsByTagName('li'); for (var i = mylis.length - 1 ; i >= 0; i --) { myul.appendChild(mylis[i]); } console.log(mylis.length); // 5
将获取到的列表元素反序重新插入ul中,那么ul列表会变成下面这样:
<ul id="myul"> <li>5</li> <li>4</li> <li>3</li> <li>2</li> <li>1</li> </ul>
我们看到列表的长度依然是5,只是位置颠倒了。这是因为每个li标签和JS中获取的标签对象存在一个对应关系,当某个标签被重新插入到页面中时,页面中对应的标签会移动到插入的位置。这就是DOM映射。
二、实现表格排序
1、使用ajax获取数据
之所以使用动态获取数据,是为了使用文档碎片绑定数据。
var res = ''; //声明一个全局变量,接收数据 var xhr = new XMLHttpRequest(); xhr.open('get', 'date.txt', false); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { res = JSON.parse(xhr.responseText); } } xhr.send(null);
此时数据就保存在了res
这个全局变量之中。
2、使用文档碎片绑定数据
var frg = document.createDocumentFragment(); for (let i = 0; i < res.length; i++) { var tr = document.createElement("tr"); for (key in res[i]) { var td = document.createElement("td"); td.innerHTML = res[i][key]; tr.appendChild(td); } frg.appendChild(tr); } tbody.appendChild(frg);
3、对表格进行排序
这里涉及的点较多
//为两列添加点击事件 for (let i = 0; i < ths.length; i++) { let curTh = ths[i]; curTh.sortFlag = -1; //用于对列进行升降序排列 curTh.index = i; //记录当前点击列的索引,便于排序操作 if (curTh.className == 'sort') { curTh.onclick = function() { sort.call(this); //改变排序函数内this的指向,让其指向当前点击列 } } } //排序方法 function sort() { //对数组元素进行排序 let target = this; //这里将this取出,因为在sort方法里需要使用该this,但是sort方法里的this是调用方法的数组 this.sortFlag *= -1; //1 代表升序 -1代表降序 let ary = listToArray(bodyTrs); //获取body数据 ary = ary.sort(function(a, b) { let one = a.cells[target.index].innerHTML; let two = b.cells[target.index].innerHTML; let oneNum = parseFloat(one); let twoNum = parseFloat(two); if (isNaN(oneNum) || isNaN(two)) { return one.localeCompare(two) * target.sortFlag; } else { return (oneNum - twoNum) * target.sortFlag; } }); //把排好序的数组重新写入页面 let frg = document.createDocumentFragment(); for (let i = 0; i < ary.length; i++) { rg.appendChild(ary[i]); } tbody.appendChild(frg); frg = null; //点击某列时,要将其他列的排序标志恢复为-1,让下次再点击任意一个标签时都是默认是升序排列 for (let i = 0; i < ths.length; i++) { if (ths[i] != this) { ths[i].sortFlag = -1; } } }
以上内容就是原生JS实现表格排序,希望能帮助到大家。
jquery中tablesorter表格排序组件是如何使用的?
js表格排序实例详解(支持int,float,date,string四种数据类型)
以上がネイティブ JS はテーブルのソートを実装しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









この記事では、Windows 11/10 で写真を撮影日順に並べ替える方法を紹介し、Windows で写真が日付順に並べ替えられない場合の対処法についても説明します。 Windows システムでは、画像ファイルを見つけやすくするために、写真を適切に整理することが重要です。ユーザーは、日付、サイズ、名前などのさまざまな並べ替え方法に基づいて写真を含むフォルダーを管理できます。さらに、必要に応じて昇順または降順を設定して、ファイルをより柔軟に整理できます。 Windows 11/10 で写真を撮影日で並べ替える方法 Windows で写真を撮影日で並べ替えるには、次の手順に従います。 [ピクチャ]、デスクトップ、または写真を配置する任意のフォルダを開きます。 リボン メニューで、

1. 新しい PPT ファイルを作成し、例として [PPT Tips] という名前を付けます。 2. [PPT Tips]をダブルクリックしてPPTファイルを開きます。 3. 例として 2 行 2 列の表を挿入します。 4. 表の境界線をダブルクリックすると、上部ツールバーに[デザイン]オプションが表示されます。 5. [シェーディング]オプションをクリックし、[画像]をクリックします。 6. [画像]をクリックすると、画像を背景にした塗りつぶしオプションダイアログボックスが表示されます。 7. ディレクトリ内で挿入したいトレイを見つけ、「OK」をクリックして画像を挿入します。 8. テーブル ボックスを右クリックして、設定ダイアログ ボックスを表示します。 9. [セルの書式設定]をクリックし、[画像を網掛けとして並べる]にチェックを入れます。 10. [中央]、[ミラー]など必要な機能を設定し、[OK]をクリックします。注: デフォルトでは、表に画像が入力されます。

Outlook には、作業をより効率的に管理するための多くの設定と機能が用意されています。その 1 つは、ニーズに応じてメールを分類できる並べ替えオプションです。このチュートリアルでは、Outlook の並べ替え機能を使用して、送信者、件名、日付、カテゴリ、サイズなどの基準に基づいてメールを整理する方法を学習します。これにより、重要な情報の処理と検索が容易になり、生産性が向上します。 Microsoft Outlook は、電子メールやカレンダーのスケジュールを簡単に一元管理できる強力なアプリケーションです。電子メールの送受信、整理が簡単にできるほか、内蔵のカレンダー機能により今後のイベントや予定を簡単に追跡できます。 Outlo の使い方

帳票を上手に作成できることは、経理や人事、財務の分野だけでなく、多くの営業職にとっても帳票の作成を学ぶことは非常に重要です。なぜなら、販売に関連するデータは非常に大規模かつ複雑であり、問題を説明するために文書に単純に記録することはできないからです。より多くの営業マンがExcelを使った表作成に習熟できるよう、売上予測に関する表作成の課題を編集部が紹介しますので、お困りの友人は必見です! 1. [売上予測・目標設定]xlsmを開き、各テーブルに格納されているデータを分析します。 2. 新規に[空のワークシート]を作成し、[セル]を選択し、[ラベル情報]を入力します。下に[ドラッグ]し、月を[塗りつぶします]。 [その他]のデータを入力し、[

1. ワークシートを開き、[スタート]-[条件付き書式]ボタンを見つけます。 2. [列の選択] をクリックし、条件付き書式を追加する列を選択します。 3. [条件付き書式]ボタンをクリックするとオプションメニューが表示されます。 4. [条件付きルールを強調表示]-[間]を選択します。 5. ルールを入力します: 20、24、濃い緑色のテキストと濃い塗りつぶし。 6. 確認後、選択した列のデータは、設定に従って対応する数値、テキスト、セル ボックスで色付けされます。 7. 競合のない条件付きルールは繰り返し追加できますが、競合するルールの場合、WPS は以前に確立された条件付きルールを最後に追加したルールに置き換えます。 8. [Between] ルール 20 ~ 24 と [Less than] 20 の後にセル列を繰り返し追加します。 9. ルールを変更する必要がある場合は、ルールをクリアしてからルールをリセットします。

Word の表で数を数えるという問題に遭遇することがあります。通常、このような問題に遭遇すると、ほとんどの生徒は Word の表を Excel にコピーして計算しますが、黙って電卓を手に取る生徒もいます。簡単に計算する方法はありますか?もちろんありますが、実はWordでも合計額を計算することができます。それで、その方法を知っていますか?今日は、一緒に見ていきましょう!困っている友達はすぐに集めてください。手順の詳細: 1. まず、コンピューターで Word ソフトウェアを開き、処理する必要がある文書を開きます。 (図のように) 2. 次に、(図のように) 合計値が配置されているセルにカーソルを置き、[メニュー バー] をクリックします。

表を作るとき、真っ先に思いつくのがExcelソフトで表を作ることですが、実はWordソフトを使うととても便利なのをご存知ですか?Wordソフトで表を作ると連番を入力する必要がある場合があります。いちいち手で入力するととても面倒です。実はワードソフトには数字や連番を自動で挿入できる機能があるので、エディターで自動で番号を挿入する方法を学びましょう。またはシリアル番号を Word テーブルに挿入します。 1. まず Word 文書を作成し、表を挿入します。 2. 自動シリアル番号または数字を挿入する列またはセルを選択します。 3.「スタート」-「番号」をクリックします。 4. いずれかのスタイル番号を選択します。 5.

Word ソフトは私たちにとって欠かせないものであり、頻繁に使用する必要があります。以前 Word ソフトを使用して表を編集する方法を学んだことがあります。しかし、誤って表を縦横に編集してしまった場合、時間を無駄にしたくないのです。 -作成するのですが、テーブルの縦横を変更することはできますか?毛織物?答えはもちろん「はい」です。次に、Word で表を縦横に入れ替える方法をエディターが詳しく紹介しますので、一緒に学びましょう。まず、以下の Word 表の行と列を交換する必要があります。これを行うには、まずテーブル全体を選択し、次に右クリックしてコピー機能を選択する必要があります。ステップ 2: コピーを選択した後、Word を最小化し、Excel テーブルを開き、右クリックして貼り付けを選択し、Exc に貼り付けます。
