2016-12-12 124 views
0

我正在使用一個簡單的http服務器並創建一個上下文來打印我的記錄器輸出。自動滾動加載html頁面

  server.createContext("/log", new HttpHandler() { 

      @Override 
      public void handle(final HttpExchange t) throws IOException { 
       t.getResponseHeaders().set("Content-Type", "text/html; charset=UTF-8"); 
       t.sendResponseHeaders(200, 0); 
       Writer out = new OutputStreamWriter(t.getResponseBody(), "UTF-8"); 
       out.write("<pre>"); 
       Semaphore s = new Semaphore(0); 

       ExecutionContext.setLogger(new ILogger() { 

        @Override 
        public void log(String message) { 
         try { 
          out.write(message); 
          out.flush(); 
         } catch (IOException e) { 
          s.release(); 
         } 
        } 
       }); 

       try { 
        s.acquire(); 
       } catch (InterruptedException e) { 
       } 

      } 

除非連接結束(例如用戶關閉瀏覽器選項卡),否則OutputStream從不關閉。 它按預期工作,除了我的瀏覽器沒有滾動到可用的新數據。

我知道可以使用JavaScript滾動到div,但我找不到一個很好的方法來做到這一點(每次有新數據可用時,我都需要調用JavaScript代碼,即使可以, div不會在頁面的末尾,因爲頁面始終在更新...)

您是否有解決方案?

感謝

編輯: 解決方案由森雅各布的回答啓發: server.createContext( 「/日誌」,新的HttpHandler(){

  @Override 
      public void handle(final HttpExchange t) throws IOException { 
       t.getResponseHeaders().set("Content-Type", "text/html; charset=UTF-8"); 
       t.sendResponseHeaders(200, 0); 
       Writer out = new OutputStreamWriter(t.getResponseBody(), "UTF-8"); 
       StringBuilder sb = new StringBuilder(); 
       sb.append("<html>\n"); 
       sb.append("<body>\n"); 
       sb.append("<pre id='logger'></pre>\n"); 
       sb.append("<script>\n"); 
       sb.append("var logger = document.getElementById('logger');\n"); 
       sb.append("\n"); 
       sb.append("function addLog(s) {\n"); 
       sb.append(" // scroll only if already at the end of the page\n"); 
       sb.append(" var scroll = document.body.scrollTop + document.body.clientHeight == document.body.scrollHeight\n"); 
       sb.append(" logger.innerHTML += s;\n"); 
       sb.append(" if(scroll) {\n"); 
       sb.append(" window.scrollTo(0,document.body.scrollHeight);\n"); 
       sb.append(" }\n"); 
       sb.append("}</script>\n"); 

       out.write(sb.toString()); 

       Semaphore s = new Semaphore(0); 

       ExecutionContext.setLogger(new ILogger() { 

        @Override 
        public void log(String message) { 
         try { 
          message = StringEscapeUtils.escapeEcmaScript(message); 
          out.write("\n<script>addLog('" + message + "')</script>"); 
          out.flush(); 
         } catch (IOException e) { 
          s.release(); 
         } 
        } 
       }); 

       try { 
        s.acquire(); 
       } catch (InterruptedException e) { 
       }      
      } 
+0

頁面無法以比JavaScript更快的速度更新,因此您可能會失去真正的「實時」更新,但滾動應該適用於使用示例Sen Jacob在其答案中收到的每個日誌。 – petryuno1

+0

我不知道爲什麼我會失去更新。隨着我在我的帖子中添加的解決方案,一切都應該沒問題,因爲我只在更新頁面內容後才滾動 – jaudo

回答

3

這裏是一個example JavaScript代碼,在那裏你可以滾動到新添加的日誌條目。

var logger = document.getElementById("logger"); 
 
function addLog() { 
 
\t // add new log entry 
 
    var div = document.createElement("div"); 
 
    div.innerHTML = "log - " + Date.now(); 
 
    logger.appendChild(div); 
 
    // scroll to new log 
 
    logger.scrollTop = logger.scrollHeight; 
 
} 
 
// simulate http response 
 
var timer = setInterval(addLog, 1000); 
 
window.onbeforeunload = clearInterval.bind(window, timer);
#logger { 
 
    height: 10em; 
 
    overflow-y: auto; 
 
}
<div id="logger"></div>

+1

謝謝,我改編了您的解決方案以獲取我想要的內容 – jaudo