js 彈出菜單/窗口效果
更新時(shí)間:2011年10月30日 20:06:53 作者:
想象一下,你把一個(gè)重要內(nèi)容放在一個(gè)彈出窗口,又不聚集到這個(gè)窗口。讓使用屏幕閱讀器的同學(xué)情何以堪,只有當(dāng)他們 tab 到這頁(yè)面結(jié)束,還繼續(xù) tab,才可能找到這個(gè)彈窗
是不是應(yīng)該為彈出菜單提供更好的可訪問(wèn)支持?這篇文章將涉及到3種常見(jiàn)的彈窗:
window.open 新建的瀏覽器窗口
<iframe /> 創(chuàng)建的窗口
頁(yè)面 DOM 創(chuàng)建的偽彈出窗口:如彈出 tips 等
一、當(dāng)頁(yè)面無(wú) JS 的時(shí)候
通常來(lái)說(shuō),無(wú) JS 的情況那就按 HTML 的行為來(lái)做事。讓鏈接可以鏈接,就已經(jīng)解決。比較簡(jiǎn)單,我們簡(jiǎn)單帶過(guò):
1. window.open 新建的瀏覽器窗口:盡量讓 JS 觸發(fā)器綁定在 <a /> 上,并把 a 鏈接到一個(gè)新的頁(yè)面,即可。
// 鏈接與 window.open 的目標(biāo)相同
<a href="/target.html" target="_blank">[open window]</a>
// 記得阻止鏈接有默認(rèn)行為,不然有 JS 的時(shí)候會(huì)打開(kāi)兩次
window.open('./iframe.html', 'name', 'height=300,width=500');
return false;
2. <iframe /> 創(chuàng)建的窗口:如果是用 JS 動(dòng)態(tài)創(chuàng)建的,那么記得觸發(fā)器也應(yīng)該像 window.open 的方法一樣,把解法鏈接寫(xiě)在一個(gè) <a /> 上,讓用戶通過(guò)鏈接來(lái)訪問(wèn)。而如果是隱藏的,那么盡量來(lái)使用 <noscript /> 來(lái)隱藏,再用 JS 讓其正常顯示出來(lái);或者高度為 0 的空 iframe 。這樣即可保證在有 JS 的時(shí)候可用,而在無(wú) JS 的時(shí)候可以正常顯示。詳細(xì)應(yīng)用可以參照:支付寶新首頁(yè)的幾點(diǎn)前端實(shí)踐。
// 動(dòng)態(tài)創(chuàng)建,請(qǐng)盡量使用這種方法,因?yàn)?IE8 不能用 JS focus 到動(dòng)態(tài)創(chuàng)建的 focusable 元素
// 而空 src 則請(qǐng)使用 javascript:'' 這種方式,因?yàn)檫@是解決性能的最好方式,詳見(jiàn):空路徑對(duì)頁(yè)面性能影響的解決方案
<a href="/target.html" target="_blank">[open iframe]</a>
<iframe src="javascript:''" frameborder=0 id="theframe"></iframe>
// js
document.getElementById('theframe').src = '/target.html'
3. 頁(yè)面 DOM 創(chuàng)建的偽彈出窗口:使用 <noscript /> 來(lái)隱藏。鏈接用錨點(diǎn)。
<a href="#target">[open current page DOM]</a>
... 很多很多東西隔在中間 ...
<noscript><div id="target">content</div></noscript>
二、大多數(shù)情況下
大數(shù)多情況下,用戶的瀏覽器都是有開(kāi)啟 JS 的。而我們要做的是:focus 到彈出的窗口,并且第一個(gè) tab 就可以訪問(wèn)里面的內(nèi)容。聽(tīng)過(guò)來(lái)挺簡(jiǎn)單的,hub? 先看看 DEMO:
預(yù)覽:可訪問(wèn)彈出菜單/窗口
1. window.open 新建的瀏覽器窗口:focus 到新建的窗口即可。
// 引用自:QuickMode - popups
function popitup(url) {
newwindow=window.open(url,'name','height=200,width=150');
if (window.focus) {
// focus 到新建窗口
newwindow.focus();
}
// 阻止觸發(fā)器的默認(rèn)行為
return false;
}
2. <iframe /> 創(chuàng)建的窗口:調(diào)試了好久,IE8/9 需要等 iframe onload 成功后 setTimeout 來(lái) hack;firefox 不能使用 ifrcontentWindow.focus(),只能用 iframe.focus()。綜合起來(lái)需要這樣的代碼:
// for all except firefox
setTimeout(function(){
f.contentWindow.focus();
}, 50);
// hack for firefox
navigator.userAgent.toLowerCase().indexOf('firefox') !== -1 && f.focus();
3. 頁(yè)面 DOM 創(chuàng)建的偽彈出窗口:對(duì)于 dom,除了 <a /> <input /> 等這些 focusable 元素(W3C SPEC),都是不可以 focus 的。那么當(dāng)需要 focus 到一個(gè) div 時(shí),我們有什么方法可以做到呢?通常來(lái)說(shuō),我們可以設(shè)置 Tabindex 來(lái)讓像 <div /> 這樣的非 focusable 元素可以觸發(fā) focus 事件。但我們想要的時(shí)真正 focus 到一個(gè)地方,以便于使用 tab 來(lái)訪問(wèn)這個(gè)區(qū)域的內(nèi)容,所以這種方法對(duì)我們等于無(wú)用。
目前還沒(méi)有比較好的方法(對(duì)于我能想到的和找到的),所以目前來(lái)說(shuō),我們只能利用一個(gè) focusable 元素來(lái)創(chuàng)建 focus 目標(biāo)。我們可以這樣做:
<a href="#" class="getfocus">Get focus</a>
<input title="testing" />
但問(wèn)題是,對(duì)于這個(gè)鏈接對(duì)于我們來(lái)說(shuō)是毫無(wú)作用的,我們需要隱藏他,又能 focus 到。但 display:none 的時(shí)候是不能 focus 的。對(duì)于隱藏 來(lái)說(shuō),這里也不想說(shuō)太多。推薦看看這篇文章:使用clip隱藏內(nèi)容。那么我們可以這樣來(lái) hack 我們的這個(gè)鏈接:
// html: 注意用 hidefocus 來(lái)刪除虛線框
<a href="#" class="getfocus" hidefocus>Get focus</a>
// CSS: 使用 clip
.getfocus{
position:relative;
clip:rect(1px 1px 1px 1px);
clip:rect(1px, 1px, 1px, 1px);
}
// javascript: 記得把 <a /> 放在這個(gè) DOM 結(jié)構(gòu)的最前面方便自上至下 tab 下去
a.focus()
三、總結(jié):
至此,重要的技術(shù)實(shí)現(xiàn)點(diǎn)也已經(jīng)說(shuō)明白。代碼請(qǐng)見(jiàn)這個(gè)粗陋的 DEMO,雖然只是沒(méi)有特別優(yōu)化的一段代碼,但相信可以解決很多問(wèn)題。對(duì)于可訪問(wèn)性,我們要走的路還有很多。一點(diǎn)點(diǎn)來(lái)吧,從今天開(kāi)始。
window.open 新建的瀏覽器窗口
<iframe /> 創(chuàng)建的窗口
頁(yè)面 DOM 創(chuàng)建的偽彈出窗口:如彈出 tips 等
一、當(dāng)頁(yè)面無(wú) JS 的時(shí)候
通常來(lái)說(shuō),無(wú) JS 的情況那就按 HTML 的行為來(lái)做事。讓鏈接可以鏈接,就已經(jīng)解決。比較簡(jiǎn)單,我們簡(jiǎn)單帶過(guò):
1. window.open 新建的瀏覽器窗口:盡量讓 JS 觸發(fā)器綁定在 <a /> 上,并把 a 鏈接到一個(gè)新的頁(yè)面,即可。
復(fù)制代碼 代碼如下:
// 鏈接與 window.open 的目標(biāo)相同
<a href="/target.html" target="_blank">[open window]</a>
// 記得阻止鏈接有默認(rèn)行為,不然有 JS 的時(shí)候會(huì)打開(kāi)兩次
window.open('./iframe.html', 'name', 'height=300,width=500');
return false;
2. <iframe /> 創(chuàng)建的窗口:如果是用 JS 動(dòng)態(tài)創(chuàng)建的,那么記得觸發(fā)器也應(yīng)該像 window.open 的方法一樣,把解法鏈接寫(xiě)在一個(gè) <a /> 上,讓用戶通過(guò)鏈接來(lái)訪問(wèn)。而如果是隱藏的,那么盡量來(lái)使用 <noscript /> 來(lái)隱藏,再用 JS 讓其正常顯示出來(lái);或者高度為 0 的空 iframe 。這樣即可保證在有 JS 的時(shí)候可用,而在無(wú) JS 的時(shí)候可以正常顯示。詳細(xì)應(yīng)用可以參照:支付寶新首頁(yè)的幾點(diǎn)前端實(shí)踐。
復(fù)制代碼 代碼如下:
// 動(dòng)態(tài)創(chuàng)建,請(qǐng)盡量使用這種方法,因?yàn)?IE8 不能用 JS focus 到動(dòng)態(tài)創(chuàng)建的 focusable 元素
// 而空 src 則請(qǐng)使用 javascript:'' 這種方式,因?yàn)檫@是解決性能的最好方式,詳見(jiàn):空路徑對(duì)頁(yè)面性能影響的解決方案
<a href="/target.html" target="_blank">[open iframe]</a>
<iframe src="javascript:''" frameborder=0 id="theframe"></iframe>
// js
document.getElementById('theframe').src = '/target.html'
3. 頁(yè)面 DOM 創(chuàng)建的偽彈出窗口:使用 <noscript /> 來(lái)隱藏。鏈接用錨點(diǎn)。
復(fù)制代碼 代碼如下:
<a href="#target">[open current page DOM]</a>
... 很多很多東西隔在中間 ...
<noscript><div id="target">content</div></noscript>
二、大多數(shù)情況下
大數(shù)多情況下,用戶的瀏覽器都是有開(kāi)啟 JS 的。而我們要做的是:focus 到彈出的窗口,并且第一個(gè) tab 就可以訪問(wèn)里面的內(nèi)容。聽(tīng)過(guò)來(lái)挺簡(jiǎn)單的,hub? 先看看 DEMO:
預(yù)覽:可訪問(wèn)彈出菜單/窗口
1. window.open 新建的瀏覽器窗口:focus 到新建的窗口即可。
復(fù)制代碼 代碼如下:
// 引用自:QuickMode - popups
function popitup(url) {
newwindow=window.open(url,'name','height=200,width=150');
if (window.focus) {
// focus 到新建窗口
newwindow.focus();
}
// 阻止觸發(fā)器的默認(rèn)行為
return false;
}
2. <iframe /> 創(chuàng)建的窗口:調(diào)試了好久,IE8/9 需要等 iframe onload 成功后 setTimeout 來(lái) hack;firefox 不能使用 ifrcontentWindow.focus(),只能用 iframe.focus()。綜合起來(lái)需要這樣的代碼:
復(fù)制代碼 代碼如下:
// for all except firefox
setTimeout(function(){
f.contentWindow.focus();
}, 50);
// hack for firefox
navigator.userAgent.toLowerCase().indexOf('firefox') !== -1 && f.focus();
3. 頁(yè)面 DOM 創(chuàng)建的偽彈出窗口:對(duì)于 dom,除了 <a /> <input /> 等這些 focusable 元素(W3C SPEC),都是不可以 focus 的。那么當(dāng)需要 focus 到一個(gè) div 時(shí),我們有什么方法可以做到呢?通常來(lái)說(shuō),我們可以設(shè)置 Tabindex 來(lái)讓像 <div /> 這樣的非 focusable 元素可以觸發(fā) focus 事件。但我們想要的時(shí)真正 focus 到一個(gè)地方,以便于使用 tab 來(lái)訪問(wèn)這個(gè)區(qū)域的內(nèi)容,所以這種方法對(duì)我們等于無(wú)用。
目前還沒(méi)有比較好的方法(對(duì)于我能想到的和找到的),所以目前來(lái)說(shuō),我們只能利用一個(gè) focusable 元素來(lái)創(chuàng)建 focus 目標(biāo)。我們可以這樣做:
<a href="#" class="getfocus">Get focus</a>
<input title="testing" />
但問(wèn)題是,對(duì)于這個(gè)鏈接對(duì)于我們來(lái)說(shuō)是毫無(wú)作用的,我們需要隱藏他,又能 focus 到。但 display:none 的時(shí)候是不能 focus 的。對(duì)于隱藏 來(lái)說(shuō),這里也不想說(shuō)太多。推薦看看這篇文章:使用clip隱藏內(nèi)容。那么我們可以這樣來(lái) hack 我們的這個(gè)鏈接:
復(fù)制代碼 代碼如下:
// html: 注意用 hidefocus 來(lái)刪除虛線框
<a href="#" class="getfocus" hidefocus>Get focus</a>
// CSS: 使用 clip
.getfocus{
position:relative;
clip:rect(1px 1px 1px 1px);
clip:rect(1px, 1px, 1px, 1px);
}
// javascript: 記得把 <a /> 放在這個(gè) DOM 結(jié)構(gòu)的最前面方便自上至下 tab 下去
a.focus()
三、總結(jié):
至此,重要的技術(shù)實(shí)現(xiàn)點(diǎn)也已經(jīng)說(shuō)明白。代碼請(qǐng)見(jiàn)這個(gè)粗陋的 DEMO,雖然只是沒(méi)有特別優(yōu)化的一段代碼,但相信可以解決很多問(wèn)題。對(duì)于可訪問(wèn)性,我們要走的路還有很多。一點(diǎn)點(diǎn)來(lái)吧,從今天開(kāi)始。
您可能感興趣的文章:
- JS彈出窗口代碼大全(詳細(xì)整理)
- js右下角彈出窗口,點(diǎn)擊可關(guān)閉效果
- javascript 控制彈出窗口
- 如何創(chuàng)建一個(gè)JavaScript彈出DIV窗口層的效果
- javascript之彈出窗口居中的代碼
- JavaScript彈出窗口方法匯總
- 23個(gè)Javascript彈出窗口特效整理
- js實(shí)現(xiàn)彈出窗口、頁(yè)面變成灰色并不可操作的例子分享
- js 模式窗口(模式對(duì)話框和非模式對(duì)話框)的使用介紹
- JAVASCRIPT模式窗口中下載文件無(wú)法接收iframe的流
- JS實(shí)現(xiàn)彈出居中的模式窗口示例
相關(guān)文章
JavaScript學(xué)習(xí)筆記之創(chuàng)建對(duì)象
在JavaScript中對(duì)象是一種基本的數(shù)據(jù)類(lèi)型,在數(shù)據(jù)結(jié)構(gòu)上是一種散列表,可以看作是屬性的無(wú)序集合,除了原始值其他一切都是對(duì)象。這篇文章主要給大家介紹JavaScript學(xué)習(xí)筆記之創(chuàng)建對(duì)象,需要的朋友參考下吧2016-03-03JavaScript基于Dom操作實(shí)現(xiàn)查找、修改HTML元素的內(nèi)容及屬性的方法
這篇文章主要介紹了JavaScript基于Dom操作實(shí)現(xiàn)查找、修改HTML元素的內(nèi)容及屬性的方法,涉及javascript dom模型及事件響應(yīng)相關(guān)操作技巧,需要的朋友可以參考下2017-01-01JavaScript實(shí)現(xiàn)簡(jiǎn)易計(jì)算器功能的兩種方法
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)簡(jiǎn)易計(jì)算器功能的兩種方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07js的math中缺少的數(shù)學(xué)方法小結(jié)
JavaScript?Math對(duì)象包含一些真正有用且強(qiáng)大的數(shù)學(xué)運(yùn)算,但它缺乏大多數(shù)其他語(yǔ)言提供的許多重要運(yùn)算,例如求和,乘積,奇數(shù)和偶數(shù)等等,本文就來(lái)介紹一下2023-08-08javascript內(nèi)置對(duì)象Math案例總結(jié)分析
今天總結(jié)一下javascript 內(nèi)置對(duì)象Math中的函數(shù)用法,順帶寫(xiě)一下常見(jiàn)的案例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03讓iframe框架網(wǎng)頁(yè)在任何瀏覽器下自動(dòng)伸縮
很多朋友都在使用iframe中遇到過(guò)不能自動(dòng)隨頁(yè)面伸縮,特別是動(dòng)態(tài)讀取頁(yè)面的時(shí)候,會(huì)出現(xiàn)滾動(dòng)條,影響美觀,今天研究一下了,發(fā)現(xiàn)了一個(gè)簡(jiǎn)單解決的辦法,可以在IE,F(xiàn)IREFOX,OPERA下使用2006-08-08ionic2屏幕適配實(shí)現(xiàn)適配手機(jī)、平板等設(shè)備的示例代碼
本篇文章主要介紹了ionic2屏幕適配實(shí)現(xiàn)適配手機(jī)、平板等設(shè)備的示例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-08-08