【问题标题】:How do I make a local HTML page auto-refresh on file change?如何使本地 HTML 页面在文件更改时自动刷新?
【发布时间】:2018-07-29 06:01:24
【问题描述】:

我在默认浏览器中通过file:// 协议查看本地HTML 文件。

我想在 HTML 文件中添加一些代码/脚本,以便在文件更改时(理想情况下是在更改吸入的 CSS 文件时)浏览器刷新页面。

我尝试通过

包含 Live.js
<script type="text/javascript" src="http://livejs.com/live.js"></script>

但它似乎对通过file:// 访问的文件没有任何影响。 - 任何已知的解决方案在这里有效?

PS 1:我找到了another question relating to this problem,但它没有解决本地文件的情况。

PS 2: 我知道我可以通过

定期重新加载页面
<meta http-equiv="refresh" content="1">

但这不是我需要的;我需要在更改时重新加载。

【问题讨论】:

  • 如果您只是下载 live.js 并链接到本地​​副本而不是 livejs.com/live.js,会发生什么?我会先试试。
  • 你用的是什么编辑器?
  • @Mark 好主意,但不起作用。 (我刚试过。)
  • @Jacob Emacs。我确定文件被写入磁盘(使用新的时间戳)。当我在浏览器中手动重新加载时,更改就会通过。
  • Live.js 不支持本地文件。检查你的控制台输出。

标签: javascript html page-refresh local-files


【解决方案1】:

更通用的解决方案

单靠Javascript似乎无法解决这个问题。在浏览器重新添加它们过去对执行此操作的支持之前,我认为没有完美的通用解决方案。

虽然我认为我之前的 Emacs 解决方案是一个不错的解决方案,但对于使用没有内置 Web 服务器的文本编辑器的人来说,这里有另一个更广泛的答案。

使用 inotifywait

许多操作系统可以设置程序在文件被修改时执行,而无需轮询。没有适用于所有操作系统的 API,但 Linux 的 inotify 比大多数操作系统都好用且易于使用。

这是一个 shell 脚本,当它在 HTML 和 CSS 文件所在的目录中运行时,它会告诉 Firefox 在保存更改时重新加载。如果你想让它只看几个文件,你也可以用特定的文件名来调用它。

#!/bin/bash
# htmlreload
# When an HTML or CSS file changes, reload any visible browser windows.
# Usage:
# 
#     htmlreload [ --browsername ] [ files ... ]
#
# If no files to watch are specified, all files (recursively) in the
# current working directory are monitored. (Note: this can take a long
# time to initially setup if you have a lot of files).
#
# An argument that begins with a dash is the browser to control.
# `htmlreload --chrom` will match both Chromium and Chrome.

set -o errexit
set -o nounset

browser="firefox"      # Default browser name. (Technically "X11 Class")
keystroke="CTRL+F5"    # The key that tells the browser to reload.

sendkey() {
    # Given an application name and a keystroke,
    # type the key in all windows owned by that application.
    xdotool search --all --onlyvisible --class "$1" \
        key --window %@ "$2"
}

# You may specify the browser name after one or more dashes (e.g., --chromium)
if [[ "${1:-}" == -* ]]; then
    browser="${1##*-}"
    shift
fi

# If no filenames given to watch, watch current working directory.
if [[ $# -eq 0 ]]; then
    echo "Watching all files under `pwd`"
    set - --recursive "`pwd`" #Added quotes for whitespace in path
fi

inotifywait --monitor --event CLOSE_WRITE "$@" | while read; do
    #echo "$REPLY"
    sendkey $browser $keystroke
done

先决条件:inotifywait 和 xdotool

您需要安装 inotifywaitxdotool 才能正常工作。在 Debian GNU/Linux(以及后代,如 Ubuntu 和 Mint)上,您可以使用单个命令获取这些程序:

sudo apt install inotify-tools xdotool

可选:使用 Chromium

我建议使用 Firefox,因为 Chromium(和 Chrome)处理没有焦点的窗口中的输入的方式很奇怪。如果您绝对必须使用 Chromium,则可以改用此 sendkey() 例程:

sendkeywithfocus() {
    # Given an application name and a keystroke, give each window
    # focus and type the key in all windows owned by that application.

    # This is apparently needed by chromium, but is annoying because
    # whatever you're typing in your text editor shortly after saving
    # will also go to the chromium window. 

    # Save previous window id so we can restore focus.
    local current_focus="$(xdotool getwindowfocus)"

    # For each visible window, focus it and send the keystroke.
    xdotool search --all --onlyvisible --class "$1" \
        windowfocus \
        key --window %@ "$2"

    # Restore previous focus.
    xdotool windowfocus "$current_focus" 
}

可选:在 Wayland 工作

我尚未对其进行测试,但得知 Wayland 现在有一个名为 ydotool 的程序,它是 xdotool 的替代品。

【讨论】:

    【解决方案2】:

    Emacs 不耐烦模式

    在其中一个 cmets 中,提问者提到他们使用 Emacs 文本编辑器。 Emacs 有一个简单的解决方案,可以在您键入时实时更新 HTML(和 CSS):Impatient Mode

    它使用 Emacs Web 服务器来提供一个带有 Javascript 的页面,该页面显示每次击键时的实时更新。

    安装

    如果你有设置MELPA,可以轻松安装不耐烦模式

    M-x package-install
    

    或者,如果您更喜欢手动安装,请参阅下面的说明。

    使用不耐烦模式

    只有三个步骤:

    1. 运行一次:

       M-x httpd-start
      
    2. 在您正在编辑的任何 HTML 或 CSS 缓冲区中运行:

       M-x impatient-mode
      
    3. 打开浏览器到http://localhost:8080/imp,然后点击缓冲区的名称。

    现在,只需输入 Emacs 并观看奇迹发生!

    使用说明

    我已经 submitted a patch 给不耐烦模式的维护者,当您运行 M-x impatient-mode 时,它会自动启动 Web 服务器并在您的浏览器中打开正确的 URL。希望这将被接受,您只需要一步即可完成所有工作。如果发生这种情况,我将编辑此答案。


    可选:手动安装

    以下不是必需的,但有些人宁愿不将 MELPA 添加到他们的 Emacs 包存储库列表中。如果是这种情况,您可以像这样安装不耐烦模式:

    cd ~/.emacs.d
    mkdir lisp
    cd lisp
    git clone https://github.com/skeeto/impatient-mode
    git clone https://github.com/skeeto/simple-httpd
    git clone https://github.com/hniksic/emacs-htmlize/
    

    现在编辑您的 .emacs 文件,以便将 ~/.emacs.d/lisp/ 的子目录添加到加载路径:

    ;; Add subdirectories of my lisp directory. 
    (let ((default-directory  "~/.emacs.d/lisp"))
         (normal-top-level-add-subdirs-to-load-path))
    (autoload 'impatient-mode "~/.emacs.d/lisp/impatient-mode/impatient-mode" "\
    Serves the buffer live over HTTP.
    
    \(fn &optional ARG)" t nil)
    

    这应该足以让不耐烦模式工作,但如果您希望它稍微快一点,您可以对 emacs lisp 文件进行字节编译。

    【讨论】:

    • 我的问题有点宽泛,但在使用 Emacs 时,这是一个 超酷 解决方案,谢谢。 :-)
    【解决方案3】:

    出于安全原因,浏览器限制对file:/// 协议的访问。在 Firefox 中,即使是扩展也不再能够访问本地文件,因此您很可能必须在本地提供文件才能使用实时重新加载脚本。如果你这样做了,你可以只使用 Live.js,但是像 this 这样的东西可能会稍微简单一些。 (需要 Node.js)

    【讨论】:

    • 是有道理的——但是提到的flymdJacob 似乎能够做到这一点。我只是简单地玩了一下它:它有一个 HTML 主文件,它通过 Javascript 读取和呈现 Markdown 文件。它确实似乎从本地 Markdown 文件中获取了生活变化,并且主文件在浏览器中打开为file:///path/to/flymd.html
    • 这样做是你想要的吗?这似乎只处理渲染 Markdown 而不是完整的 HTML/CSS。
    • 不,它不符合我的要求(因为源是 Markdown 文件,而不是 HTML)。但它向我表明,浏览器(通过 javascript)以某种方式可以俯视文件系统......
    • 如果您查看browser compatibility,他们会注意到 Chrome 不允许文件访问(有解决方法)。虽然它说 Firefox 很好,但最后一次更新是在 2016 年,因此对于当前的浏览器可能并不准确。
    猜你喜欢
    • 2013-01-08
    • 1970-01-01
    • 2021-12-02
    • 1970-01-01
    • 2015-05-17
    • 1970-01-01
    • 2020-02-08
    • 2013-03-22
    • 1970-01-01
    相关资源
    最近更新 更多