iT邦幫忙

0

求教,為何刪掉focus()後無法正常執行 ?

  • 分享至 

  • xImage

以下這段程式碼是在設定可以編改內容的表格。
這是線上教學老師寫的內容,由於不是很懂focus()的應用(我知道它是用在獲取焦點),我就試著把其中的oInput.focus()刪除掉試試。


<script type="text/javascript">
            var oTable = document.getElementsByTagName('table')[0];
            oTable.onclick = function(ev){
                ev = ev || ev;
                var self = ev.target || ev.srcElement;
                
                var oInput = document.createElement('input');
                oInput.type = 'text';
                oInput.value = self.innerHTML;
                self.innerHTML = null;
                self.appendChild(oInput);

                oInput.focus();     //試著刪掉的內容

                ev.stopPropagation ? ev.stopPropagation() :ev.cancelBubble = true;

                document.onclick = function(){
                    self.innerHTML = oInput.value;
                }

            }
        </script>

結果刪除掉後,最後面這段程式碼就好像失去效用,請問是為什麼啊??

document.onclick = function(){
self.innerHTML = oInput.value;
}

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

0
timtnlee
iT邦新手 5 級 ‧ 2018-11-12 09:33:34

不是focus的問題,這段程式本身有些問題

你預期的動作是:

點擊table -> (input自動focus) -> 輸入文字 -> 點擊其他地方

你現在試試看

點擊table -> (input自動focus) -> 故意再點一次input -> 輸入文字 -> 點擊其他地方

這段程式碼就失效了

因為你的table onClick事件又觸發了一次

這時候看看這段

oInput.value = self.innerHTML;

這時候的self.innerHTML已經不是純文字了而是包含了你剛剛塞的input tag...

看更多先前的回應...收起先前的回應...
14881411 iT邦新手 5 級 ‧ 2018-11-12 20:20:11 檢舉

嗯....我才疏學淺,其實不太懂你的意思...(慚愧)
你說這段程式碼有問題,那請問這些程式碼要怎麼改才好呢??

timtnlee iT邦新手 5 級 ‧ 2018-11-12 20:48:51 檢舉

ㄟ...怎麼說勒,這段程式是有問題沒錯,但可能那個教學只是要你了解某部分的東西(?)

我覺得你先弄懂看看出錯的原因就好吧 @@

沒有在用甚麼IDE的話,程式裡面可以先用console.log印出變數,看是否符合你的預期,還有程式有沒有正確執行。

14881411 iT邦新手 5 級 ‧ 2018-11-12 23:08:21 檢舉

我不懂出錯的原因啊,我不懂,為什麼又觸發一次table onclick就會讓程式出問題??
這堂課主要是在學事件冒泡的應用,我懂事件冒泡,但我不懂這問題出在哪裡,我甚至不知道要從哪裡開始用console.log去試。

我也有詢問線上課程的老師,但問不出答案...= =
為什麼又觸發一次table onclick就會讓程式出問題??
我知道self.innerHTML後來包含了input tag,但那又如何?這是出問題的原因嗎? 請問為什麼啊?

timtnlee iT邦新手 5 級 ‧ 2018-11-13 09:02:41 檢舉

因為你的self$event.target

應該說再點一次的時候

第一次點的是<table> 第二次就變成<input>

所以第二次的self<input>

self.innerHTML 是 input value

然後self.appendChild(oInput)變成:

https://ithelp.ithome.com.tw/upload/images/20181113/20110843hovVjPqXfj.jpg

所以最後你更改的 self.innerHTML<input>的 而非 <tabel>

14881411 iT邦新手 5 級 ‧ 2018-11-13 20:36:48 檢舉

喔喔,謝謝,你這樣講我比較懂了。
真希望我那個線上課程的老師也能這麼熱心解釋...

0
bizpro
iT邦大師 1 級 ‧ 2018-11-13 09:52:20

Javascript的觀念:

  1. DOM的操作.
  2. 沒別的事就打完收工: 如果沒有oInput.focus(); 這段程式碼會跑完, 建立DOM, 就沒別的事了, 打完收工, 因此不會理會document.onclick.
  3. 有事再說: 如果有oInput.focus(); 這段程式碼也會跑完, 建立DOM, 撂下一句話: 好好盯著oInput.focus();, 有事再說, document.onclick就會等著.
看更多先前的回應...收起先前的回應...
14881411 iT邦新手 5 級 ‧ 2018-11-13 21:04:04 檢舉

請問,為什麼有oInput.focus(),才會執行document.onclick啊??
沒有oInput.focus()就省略document.onclick很奇怪,document.onclick也是oTable.onclick裡的內容啊。

搞不懂這當中的因果關係,我知道DOM,也知道focus()的用處,但就是想不通為什麼有oInput.focus()才會執行document.onclick??

能再解釋的更詳細點嗎? 謝謝!

bizpro iT邦大師 1 級 ‧ 2018-11-14 09:38:02 檢舉

(思考中)

14881411 iT邦新手 5 級 ‧ 2018-11-14 21:27:07 檢舉

嗯,其他地方都還算能明白,但這句看不懂:「但oInput.focus()使oInput取得focus, 並以document.onclick監聽。」

為什麼oInput取得focus(),document.onclick就會繼續監聽??

是否因為document.onclick裡頭有oInput,所以document.onclick才會保持監聽狀態??

還是因為oInput取得focus()後會讓oTable的onclick事件繼續下去不會結束??

我在努力弄懂這當中的邏輯,很謝謝你熱心的回覆,我的線上課程老師就沒這麼有熱心和耐心!

bizpro iT邦大師 1 級 ‧ 2018-11-14 23:02:47 檢舉

因為趕著一個案子, 我看錯了您的部份程式碼, 以為和我上週踩的一個四天的坑很像, 很抱歉, 請忽略上一則回應.
剛剛寫了一個測試的程式碼, 用firefox除錯, 我看到問題是, 在table中建立了oInput後, 同時有table的onclick和document.onclick在監聽.

  1. 在沒有oInput.focus()的情形下, 你必須點擊(click)那個oInput, 造成table的onclick首先被觸發. 再建立一個新的oInput, 使得document.onclick永遠不會被觸發.
  2. 在有oInput.focus()下, 不必自己點擊成了table一部分的oInput, table的onclick也不會觸發再執行一次, 因此document.onclick就會被執行到.

也就是說, 由於oInput成了table的一部份, 如果你沒有在程式中進行oInput.focus(); 你點擊table中的oInput以取得focus來輸入的onclick事件會先被table捕捉到.

我要發表回答

立即登入回答