Javascript 自动滚动正在加载的html页面

Javascript 自动滚动正在加载的html页面,javascript,html,Javascript,Html,我正在使用一个简单的http服务器,并创建了一个上下文来打印我的记录器输出 server.createContext("/log", new HttpHandler() { @Override public void handle(final HttpExchange t) throws IOException { t.getResponseHeaders().set("Content-Ty

我正在使用一个简单的http服务器,并创建了一个上下文来打印我的记录器输出

            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) {
                }

            }
server.createContext(“/log”,新的HttpHandler(){
@凌驾
公共无效句柄(最终HttpExchange t)引发IOException{
t、 getResponseHeaders().set(“内容类型”,“text/html;charset=UTF-8”);
t、 发送响应负责人(200,0);
Writer out=新的OutputStreamWriter(t.getResponseBody(),“UTF-8”);
请写出(“”);
            @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) {
                }                    
            }
信号量s=新信号量(0); setLogger(新的ILogger(){ @凌驾 公共作废日志(字符串消息){ 试一试{ 写出(信息);
            @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) {
                }                    
            }
out.flush(); }捕获(IOE异常){ s、 释放(); } } }); 试一试{ s、 获得(); }捕捉(中断异常e){ } }
OutputStream永远不会关闭,除非连接结束(例如,用户关闭浏览器选项卡)。 它按预期工作,只是我的浏览器在可用时没有滚动到新数据

我知道可以使用javascript滚动到一个div,但我找不到一个好的方法(每次有新数据时我都需要调用javascript代码,即使可以,div也不会在页面的末尾,因为页面总是在更新…)

你有解决办法吗

谢谢

编辑: 受Sen Jacob答案启发的解决方案: createContext(“/log”,新的HttpHandler(){

@覆盖
公共无效句柄(最终HttpExchange t)引发IOException{
t、 getResponseHeaders().set(“内容类型”,“text/html;charset=UTF-8”);
t、 发送响应负责人(200,0);
Writer out=新的OutputStreamWriter(t.getResponseBody(),“UTF-8”);
StringBuilder sb=新的StringBuilder();
某人附加(“\n”);
某人附加(“\n”);
某人附加(“\n”);
某人附加(“\n”);
sb.append(“var logger=document.getElementById('logger');\n”);
某人附加(“\n”);
sb.append(“函数addLog{\n”);
sb.append(//仅当已在页面末尾时才滚动\n”);
sb.append(“var scroll=document.body.scrollTop+document.body.clientHeight==document.body.scrollHeight\n”);
sb.append(“logger.innerHTML+=s;\n”);
sb.append(“如果(滚动){\n”);
sb.append(“window.scrollTo(0,document.body.scrollHeight);\n”);
sb.追加(“}\n”);
sb.追加(“}\n”);
写出(某人写的东西);
            @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) {
                }                    
            }
信号量s=新信号量(0); setLogger(新的ILogger(){ @凌驾 公共作废日志(字符串消息){ 试一试{ message=StringEscapeUtils.escapeEcmaScript(消息); out.write(“\naddLog(“+message+”)”);
            @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) {
                }                    
            }
out.flush(); }捕获(IOE异常){ s、 释放(); } } }); 试一试{ s、 获得(); }捕捉(中断异常e){ } }
这是一个javascript代码,您可以在其中滚动到新添加的日志条目

var logger=document.getElementById(“logger”);
函数addLog(){
//添加新的日志条目
var div=document.createElement(“div”);
div.innerHTML=“log-”+Date.now();
记录器。附加子对象(div);
//滚动到新日志
logger.scrollTop=logger.scrollHeight;
}
//模拟http响应
var定时器=设置间隔(addLog,1000);
window.onbeforeunload=clearInterval.bind(窗口,计时器);
#记录器{
高度:10公分;
溢出y:自动;
}
这是一个javascript代码,您可以在其中滚动到新添加的日志条目

var logger=document.getElementById(“logger”);
函数addLog(){
//添加新的日志条目
var div=document.createElement(“div”);
div.innerHTML=“log-”+Date.now();
记录器。附加子对象(div);
//滚动到新日志
logger.scrollTop=logger.scrollHeight;
}
//模拟http响应
var定时器=设置间隔(addLog,1000);
window.onbeforeunload=clearInterval.bind(窗口,计时器);
#记录器{
高度:10公分;
溢出y:自动;
}

页面的更新速度不能超过JavaScript的运行速度,因此您可能会失去真正的“实时性”更新,但使用Sen Jacob在其答案中给出的示例,滚动应该可以在收到的每个日志上工作。我不确定为什么会丢失更新。使用我在帖子中添加的解决方案,一切都应该正常,因为我只在更新页面内容后滚动页面。页面更新速度不能超过JavaScript的运行速度,因此您可能会丢失真正的“实时”更新,但使用Sen Jacob在其回答中给出的示例,滚动应该可以在收到的每个日志上工作。我不确定为什么会丢失更新。使用我在帖子中添加的解决方案,一切都应该很好,因为我只在更新页面内容后滚动。谢谢,我调整了您的解决方案,以获得我想要的内容调整了您的解决方案以完全满足我的需求