JQuery實(shí)現(xiàn)相鄰item焦點(diǎn)移動(dòng)的示例詳解
需求
需求是A1按上下左右按鍵是選中相應(yīng)左最近,右最近,上最近,下最近的元素B
代碼設(shè)計(jì)
①所有元素需要給定一個(gè)固定i d,例如 A1 為a c_1
②通過元素的左上角、左下角、右上角、右下角位置來計(jì)算距離,上下左右對(duì)應(yīng)計(jì)算的角不一樣
③先算出水平距離,拿到水平水平距離距離相同或者相差10PX的元素
④圖片說明:
實(shí)現(xiàn)代碼
/* 通過計(jì)算兩點(diǎn)之間的相對(duì)距離,使其跳到最近的一個(gè)元素 * @param {*} el 基準(zhǔn)元素 ac_1 * @param {*} elementsArr 與基準(zhǔn)元素做比較的元素?cái)?shù)組(類數(shù)組) * 中心點(diǎn)計(jì)算法已經(jīng)棄用 */ function toClosest(el,elementsArr) { var e = event || window.event || arguments.callee.caller.arguments[0];//獲取按下按鍵對(duì)象 /* @param {*} curLi_x_l 基準(zhǔn)元素左邊橫坐標(biāo) * @param {*} curLi_x_r 基準(zhǔn)元素右邊橫坐標(biāo) * @param {*} curLi_y_t 基準(zhǔn)元素上邊縱坐標(biāo) * @param {*} curLi_y_b 基準(zhǔn)元素下邊縱坐標(biāo) * @param {*} curLi_x_c 基準(zhǔn)元素中心點(diǎn)橫坐標(biāo) * @param {*} curLi_x_c 基準(zhǔn)元素中心點(diǎn)縱坐標(biāo) */ var curLi_x_l = $('#' + el).offset().left var curLi_x_r = $('#' + el).offset().left + $('#' + el).width() var curLi_y_t = $('#' + el).offset().top var curLi_y_b = $('#' + el).offset().top + $('#' + el).height() // var curLi_x_c = $('#' + el).offset().left + $('#' + el).width()/2 // var curLi_y_c = $('#' + el).offset().top + $('#' + el).height()/2 /* @param {*} positionArr 需比較元素的坐標(biāo)信息數(shù)組*/ var positionArr = [] $.each(elementsArr, function (index, item) { if ($('#' + el).attr('id') != $(item).attr('id')) { /* @param {*} preOrNext_x_l 基準(zhǔn)元素左邊橫坐標(biāo) * @param {*} preOrNext_x_r 基準(zhǔn)元素右邊橫坐標(biāo) * @param {*} preOrNext_y_t 基準(zhǔn)元素上邊縱坐標(biāo) * @param {*} preOrNext_y_b 基準(zhǔn)元素下邊縱坐標(biāo) * @param {*} preOrNext_x_c 基準(zhǔn)元素中心點(diǎn)橫坐標(biāo) * @param {*} preOrNext_x_c 基準(zhǔn)元素中心點(diǎn)縱坐標(biāo) */ var preOrNext_x_l = $(item).offset().left var preOrNext_x_r = $(item).offset().left + $(item).width() var preOrNext_y_t = $(item).offset().top var preOrNext_y_b = $(item).offset().top + $(item).height() // var preOrNext_x_c = $(item).offset().left + $(item).width()/2 // var preOrNext_y_c = $(item).offset().top + $(item).height()/2 /* @param {*} element 被遍歷元素的坐標(biāo)信息*/ var element = {}; /* 此步會(huì)篩選需比較的元素 * @param {*} element.ac_in 比較元素標(biāo)記 * @param {*} element.distance 基準(zhǔn)元素與比較元素的中心點(diǎn)距離 * @param {*} element.x 比較元素比較點(diǎn)橫坐標(biāo) * @param {*} element.y 比較元素比較點(diǎn)縱坐標(biāo) * @param {*} element.abs_x 比較元素比較點(diǎn)縱坐標(biāo)與基準(zhǔn)元素比較點(diǎn)橫距離絕對(duì)值 * @param {*} element.abs_y 比較元素比較點(diǎn)縱坐標(biāo)與基準(zhǔn)元素比較點(diǎn)縱距離絕對(duì)值 * @param {*} element.abs_distance 比較元素比較點(diǎn)與基準(zhǔn)元素比較點(diǎn)距離 */ // element.distance = parseInt(Math.pow((curLi_x_c - preOrNext_x_c), 2) + Math.pow((curLi_y_c - preOrNext_y_c), 2)) //按'向上鍵'去左下角位置坐標(biāo),按'向下鍵'去左上角位置坐標(biāo) if (e && e.keyCode == 39 && preOrNext_x_l > curLi_x_r) { element.ac_in = $(item).attr('id') element.x = preOrNext_x_l element.y = preOrNext_y_t element.abs_y = Math.abs(preOrNext_y_t - curLi_y_t) //基準(zhǔn)元素右上角和比較元素左上角 if (curLi_y_t <= preOrNext_y_t) { element.abs_distance = parseInt(Math.pow((curLi_x_r - preOrNext_x_l), 2) + Math.pow((curLi_y_t - preOrNext_y_t), 2)) } element.abs_distance = parseInt(Math.pow((curLi_x_r - preOrNext_x_l), 2) + Math.pow((curLi_y_t - preOrNext_y_t), 2)) positionArr.push(element) } else if (e && e.keyCode == 37 && preOrNext_x_r < curLi_x_l) { element.ac_in = $(item).attr('id') element.x = preOrNext_x_r element.y = preOrNext_y_t element.abs_y = Math.abs(preOrNext_y_t - curLi_y_t) //基準(zhǔn)元素左上角和比較元素右上角 element.abs_distance = parseInt(Math.pow((curLi_x_l - preOrNext_x_r), 2) + Math.pow((curLi_y_t - preOrNext_y_b), 2)) positionArr.push(element) } else if (e && e.keyCode == 38 && preOrNext_y_b < curLi_y_t) { element.ac_in = $(item).attr('id') element.x = preOrNext_x_l element.preOrNext_x_l = preOrNext_x_l element.preOrNext_x_r = preOrNext_x_r element.y = preOrNext_y_b element.abs_x = Math.abs(preOrNext_x_l - curLi_x_l) //基準(zhǔn)元素左上角和比較元素左下角 element.abs_distance = parseInt(Math.pow((curLi_x_l - preOrNext_x_l), 2) + Math.pow((curLi_y_t - preOrNext_y_b), 2)) positionArr.push(element) } else if (e && e.keyCode == 40 && preOrNext_y_t > curLi_y_b) { element.ac_in = $(item).attr('id') element.x = preOrNext_x_l element.y = preOrNext_y_t element.preOrNext_x_l = preOrNext_x_l element.preOrNext_x_r = preOrNext_x_r element.abs_x = Math.abs(preOrNext_x_l - curLi_x_l) //基準(zhǔn)元素左下角和比較元素左上角 element.abs_distance = parseInt(Math.pow((curLi_x_l - preOrNext_x_l), 2) + Math.pow((curLi_y_b - preOrNext_y_t), 2)) positionArr.push(element) } } }) // if(positionArr){ // positionArr = positionArr.sort(function (a, b) { // return a.abs_distance - b.abs_distance // }) // if(positionArr.length>0){ // ac_in = positionArr[0].ac_in // }else{ // ac_in = el // } // } /* @param {*} same_x_positionArr 橫坐標(biāo)最近元素?cái)?shù)組*/ /* @param {*} same_x_positionArr 縱坐標(biāo)最近元素?cái)?shù)組*/ /* 尋鄰規(guī)則: ①向右,首先判斷橫距離,再判斷縱距離 ②向左,首先判斷橫距離,再判斷縱距離 ③向上,首先判斷豎距離,再判斷橫距離 ④向下,首先判斷豎距離,再判斷橫距離 */ if (e && (e.keyCode == 39 || e.keyCode == 37)) { positionArr = positionArr.sort(function (a, b) { return a.x - b.x }) var same_x_positionArr = [] if(e.keyCode == 39){ if (positionArr.length > 0) { for (var i = 0; i < positionArr.length; i++) { if (positionArr[i].x > (positionArr[0].x - 10) && positionArr[i].x < (positionArr[0].x + 10)) { same_x_positionArr.push(positionArr[i]) } } } }else if(e.keyCode == 37){ if (positionArr.length > 0) { for (var i = 0; i < positionArr.length; i++) { if (positionArr[i].x > (positionArr[positionArr.length - 1].x - 10) && positionArr[i].x < (positionArr[positionArr.length - 1].x + 10)) { same_x_positionArr.push(positionArr[i]) } } } } same_x_positionArr = same_x_positionArr.sort(function (a, b) { return a.abs_y - b.abs_y }) if (same_x_positionArr.length > 0) { ac_in = same_x_positionArr[0].ac_in } else { ac_in = el } } else if (e && e.keyCode == 38) { positionArr = positionArr.sort(function (a, b) { return a.y - b.y }) var same_y_positionArr = [] if (positionArr.length > 0) { for (var i = 0; i < positionArr.length; i++) { if (positionArr[i].preOrNext_x_l == curLi_x_l || positionArr[i].preOrNext_x_l == curLi_x_r) { same_y_positionArr.push(positionArr[i]) } else if (positionArr[i].preOrNext_x_r == curLi_x_l || positionArr[i].preOrNext_x_r == curLi_x_r) { same_y_positionArr.push(positionArr[i]) } else if (positionArr[i].preOrNext_x_l > curLi_x_l && positionArr[i].preOrNext_x_l < curLi_x_r) { same_y_positionArr.push(positionArr[i]) } else if (positionArr[i].preOrNext_x_r > curLi_x_l && positionArr[i].preOrNext_x_r < curLi_x_r) { same_y_positionArr.push(positionArr[i]) } else if (positionArr[i].preOrNext_x_l < curLi_x_l && positionArr[i].preOrNext_x_r > curLi_x_r) { same_y_positionArr.push(positionArr[i]) } } } if (same_y_positionArr.length > 0) { console.log(same_y_positionArr) same_y_positionArr = same_y_positionArr.sort(function (a, b) { return b.y - a.y }) ac_in = same_y_positionArr[0].ac_in console.log(ac_in) } else { if (positionArr.length > 0) { for (var i = 0; i < positionArr.length; i++) { if (positionArr[i].y > (positionArr[positionArr.length - 1].y - 10) && positionArr[i].y < (positionArr[positionArr.length - 1].y + 10)) { same_y_positionArr.push(positionArr[i]) } } } same_y_positionArr = same_y_positionArr.sort(function (a, b) { return a.abs_x - b.abs_x }) if (same_y_positionArr.length > 0) { ac_in = same_y_positionArr[0].ac_in } else { ac_in = el } } } else if (e && e.keyCode == 40) { positionArr = positionArr.sort(function (a, b) { return a.y - b.y }) var same_y_positionArr = [] if (positionArr.length > 0) { for (var i = 0; i < positionArr.length; i++) { if (positionArr[i].preOrNext_x_l == curLi_x_l || positionArr[i].preOrNext_x_l == curLi_x_r) { same_y_positionArr.push(positionArr[i]) } else if (positionArr[i].preOrNext_x_r == curLi_x_l || positionArr[i].preOrNext_x_r == curLi_x_r) { same_y_positionArr.push(positionArr[i]) } else if (positionArr[i].preOrNext_x_l > curLi_x_l && positionArr[i].preOrNext_x_l < curLi_x_r) { same_y_positionArr.push(positionArr[i]) } else if (positionArr[i].preOrNext_x_r > curLi_x_l && positionArr[i].preOrNext_x_r < curLi_x_r) { same_y_positionArr.push(positionArr[i]) } else if (positionArr[i].preOrNext_x_l < curLi_x_l && positionArr[i].preOrNext_x_r > curLi_x_r) { same_y_positionArr.push(positionArr[i]) } } } if (same_y_positionArr.length > 0) { console.log(same_y_positionArr) same_y_positionArr = same_y_positionArr.sort(function (a, b) { return a.y - b.y }) ac_in = same_y_positionArr[0].ac_in } else { if (positionArr.length > 0) { for (var i = 0; i < positionArr.length; i++) { if (positionArr[i].y > (positionArr[0].y - 10) && positionArr[i].y < (positionArr[0].y + 10)) { same_y_positionArr.push(positionArr[i]) } } } same_y_positionArr = same_y_positionArr.sort(function (a, b) { return a.abs_x - b.abs_x }) if (same_y_positionArr.length > 0) { ac_in = same_y_positionArr[0].ac_in } else { ac_in = el } } } return ac_in }
設(shè)計(jì)理念
主要是根據(jù)當(dāng)前元素的上下左右四個(gè)角,與被比較元素的上下左右四個(gè)角,以及按鍵時(shí)間,按規(guī)則來確定下一個(gè)到底是誰。之所以不用元素中心點(diǎn)之間的距離來比較,還是因?yàn)樾枨蟮膯栴}。
用處
在機(jī)頂盒H5頁(yè)面中使用,當(dāng)然考慮到語法適配問題,以及性能問題,可以做各自的優(yōu)化。例如,我這個(gè)頁(yè)面的用法就有所不同,是比較當(dāng)前元素,與當(dāng)前欄所有元素或者上一欄或者下一欄元素比較,不會(huì)使用所有元素去比較,避免太多的代碼執(zhí)行。
疑問
機(jī)頂盒的項(xiàng)目算是小眾項(xiàng)目。我剛接手的時(shí)候,頁(yè)面展示是靜態(tài)的,所以指定下一個(gè)選中目標(biāo)就可以了。但是后面就有了改變,我的頁(yè)面欄目是動(dòng)態(tài)的,所有欄目運(yùn)營(yíng)隨意配置順序。經(jīng)過一番思考之后,使用了這種方法。其實(shí)做個(gè)工作的同行應(yīng)該也有挺多的,我很想知道大家是怎么做的,如何更有效率。
到此這篇關(guān)于JQuery實(shí)現(xiàn)相鄰item焦點(diǎn)移動(dòng)的示例詳解的文章就介紹到這了,更多相關(guān)JQuery相鄰item焦點(diǎn)移動(dòng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
jQuery中innerHeight()方法用法實(shí)例
這篇文章主要介紹了jQuery中innerHeight()方法用法,實(shí)例分析了innerHeight()方法的功能、定義及獲取第一個(gè)匹配元素內(nèi)部區(qū)域高度的使用技巧,需要的朋友可以參考下2015-01-01基于jquery實(shí)現(xiàn)自定義的audio
最近接到一個(gè)古早的項(xiàng)目變更,設(shè)計(jì)的音樂播放的功能是自定義的樣式,對(duì)于jquery的項(xiàng)目第一反應(yīng)是先找插件,然而找了半天沒找到,最后只能自己實(shí)現(xiàn),文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下2023-12-12使用jQuery實(shí)現(xiàn)星級(jí)評(píng)分代碼分享
本文給大家分享的是一段使用jQuery制作的星級(jí)評(píng)分的代碼,非常大氣漂亮,功能也很實(shí)用,這里推薦個(gè)大家。2014-12-12jquery實(shí)現(xiàn)的帶縮略圖的焦點(diǎn)圖片切換(自動(dòng)播放/響應(yīng)鼠標(biāo)動(dòng)作)
帶縮略圖的焦點(diǎn)圖片切換在實(shí)際應(yīng)用中很廣泛的,鼠標(biāo)滑上焦點(diǎn)圖時(shí)停止自動(dòng)播放,滑出時(shí)開始自動(dòng)播放及鼠標(biāo)滑上后顯示按鈕、顯示大圖等等,感興趣的朋友可以了解下2013-01-01