V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
canadahetian
V2EX  ›  问与答

Jquery 或 js 如何操作主页面下 iframe 里的锚点?

  •  
  •   canadahetian · 2020-04-13 08:51:04 +08:00 · 2176 次点击
    这是一个创建于 1687 天前的主题,其中的信息可能已经有所发展或是发生改变。

    主页里包含了一个 iframe, JS 代码只能写在主页面里, 是否可以实现通过 主页面的 js 脚本,操作 iframe 里的锚点属性 主页面 点击 跳转到 iframe 下的对应锚点元素 testpoint

    请各位前端前辈,指点一下.非常感谢!

    23 条回复    2020-04-14 06:07:57 +08:00
    gqbre
        1
    gqbre  
       2020-04-13 09:02:51 +08:00
    首先要同域
    albyBen
        2
    albyBen  
       2020-04-13 09:10:51 +08:00
    完成这件事的前提是你能修改 iframe 内的 js 代码,通过 hashchange 或者 postMessage 检测到主页面 js 代码的修改内容,然后在做锚点跳转操作;貌似百度富文本编辑器 ueditor 某个版本可以对 iframe 进行处理,能不能实现需要你自己去探索了
    canadahetian
        3
    canadahetian  
    OP
       2020-04-13 09:32:59 +08:00
    @gqbre 绝对同域 在同一个服务器的,同一个项目文件夹,
    主 html 路径 /项目 /static/index.html
    iframe 包含的 html 路径 /项目 /static/html/1.html
    请指点一下,拜托了,感谢
    cydian
        4
    cydian  
       2020-04-13 09:35:49 +08:00 via Android
    父对子 只要同域什么都能做啊
    rabbbit
        5
    rabbbit  
       2020-04-13 09:36:31 +08:00   ❤️ 1
    document.querySelector("iframe").contentWindow
    canadahetian
        6
    canadahetian  
    OP
       2020-04-13 09:57:39 +08:00
    var x_text = "test1";
    document.querySelector("iframe").contentWindow.animate({scrollTop: $("a[name="+x_text+"]").offset().top}, 500);
    @cydian
    @rabbbit
    报错:
    Uncaught TypeError: document.querySelector(...).contentWindow.animate is not a function
    不能直接这么用吗?
    CodingMonkey
        7
    CodingMonkey  
       2020-04-13 10:01:55 +08:00
    @canadahetian document.querySelector("iframe").contentWindow 拿到的是 window,哪来的 animate() 方法?
    canadahetian
        8
    canadahetian  
    OP
       2020-04-13 10:21:26 +08:00
    @CodingMonkey
    document.querySelector("iframe").contentWindow.document.body.animate({scrollTop: $("a[name="+x_text+"]").offset()}, 500)
    @rabbbit

    这样写,也没有滚动到锚点位置,请指点一下.
    cydian
        9
    cydian  
       2020-04-13 10:24:55 +08:00 via Android
    直接对子操作啊。
    你对父操作干啥?
    canadahetian
        10
    canadahetian  
    OP
       2020-04-13 10:35:08 +08:00
    @cydian 怎么操作啊大神,指点一下,我前端 Noober
    hshpy
        11
    hshpy  
       2020-04-13 10:38:26 +08:00
    试试改 src 属性的 url
    cydian
        12
    cydian  
       2020-04-13 10:39:04 +08:00   ❤️ 1
    @canadahetian #10 你的描述不够清晰
    子窗口有没有锚点
    你是想要插入锚点然后跳转
    还是创建 iframe 的时候自动划到锚点
    还是什么?
    fengbjhqs
        13
    fengbjhqs  
       2020-04-13 11:06:12 +08:00
    有个不成熟的想法,如果子 iframe 是服务器端渲染,可以获取到文本修改后转 blob,在放到 iframe 里
    canadahetian
        14
    canadahetian  
    OP
       2020-04-13 11:11:23 +08:00
    通过主页面的按钮,点击后, 滚动到 iframe 子页面 <a name="docker-架构" class="md-header-anchor"></a>这个位置

    现在不报错了,但是没有滚动

    拜托了,大神,就查这一个功能了.

    主页面 index.html 代码如下
    <html>
    ...
    <iframe src="test1.html" width="100%" frameborder="0" scrolling="no" id="external-frame" name="external-frame"
    onload="setIframeHeight(this)"></iframe>
    ...

    /* 点击这个按钮, 跳转到锚点 docker-架构 的位置*/
    <button onclick="bookmark_button_click(this)">docker-架构</button>




    <script>
    function bookmark_button_click(self){
    var x_text = self.innerText // 值是:docker-架构
    document.querySelector("iframe").contentDocument.documentElement.querySelector("a[name="+x_text+"]")
    }
    <script>

    <html>


    test1.html 代码如下:
    <html>
    <body>
    ....
    <h3><a name="centos7" class="md-header-anchor"></a><span>Centos7</span></h3>
    ...
    <h2><a name="container 容器相关命令" class="md-header-anchor"></a><span>Container 容器相关命令</span></h2>
    ...
    <h2><a name="docker-架构" class="md-header-anchor"></a><span>Docker 架构</span></h2>
    ...
    </body>
    <html>



    @cydian
    cydian
        15
    cydian  
       2020-04-13 12:21:46 +08:00
    var v2 = document.getElementById('id').contentWindow;
    var v22 = v2.document;
    v22.scroll(500,500);
    元素的位置自己另写代码定位吧。
    canadahetian
        16
    canadahetian  
    OP
       2020-04-13 20:48:03 +08:00 via iPhone
    @cydian 大哥你是谁别百度个代码的吗?你看一下我给你回复的代码?你写的这些,我不是已经写了吗,来电 Stackflow 精神呗
    cydian
        17
    cydian  
       2020-04-13 21:27:42 +08:00 via Android
    @canadahetian 所以你到底是没明白怎么控制 iframe 还是获取元素位置?
    我或许没有理解你的需求。
    抱歉打扰了。
    你的代码我是认真看了,你想实现的功能,我也回复了。
    cydian
        18
    cydian  
       2020-04-13 21:29:07 +08:00 via Android
    @canadahetian 还有,你是歧视百度出来的代码吗?
    这么厉害怎么到现在都还没有解决?
    解决问题的代码就是好代码,你管他从哪里来的,合法合规合情合理。
    对你的回复无语。
    canadahetian
        19
    canadahetian  
    OP
       2020-04-13 22:49:54 +08:00
    @cydian 不是哥们,你的代码运行,可不行啊,而且我之前不是回复你了吗?
    这个代码已经在之前就测试了,没法定位到 iframe 的 a 元素位置,页面文斯不懂啊.
    canadahetian
        20
    canadahetian  
    OP
       2020-04-13 22:58:49 +08:00
    @cydian
    var iframe_windows = document.getElementById("external-frame").contentWindow;
    var iframe_document = iframe_windows.document;
    iframe_document.scroll(500,500);

    直接报错.
    Uncaught TypeError: iframe_document.scroll is not a function
    canadahetian
        21
    canadahetian  
    OP
       2020-04-13 23:03:43 +08:00
    @cydian 哥们,你的理解能力真的是,幸好没联想到鸦片战争?
    你从哪几个关键字,联想到我歧视百度的?
    我的意思是说,我的代码都已经精简完,放在哪里了.你就看着代码,直接指点不就可以了吗?
    还单独又起一个名字,把之前
    document.querySelector("iframe").contentWindow 这个方法,改成了
    document.getElementById('id').contentWindow
    这么改有什么区别吗?大神?
    cydian
        22
    cydian  
       2020-04-13 23:19:24 +08:00 via Android
    @canadahetian 抱歉 之前的一些回复可能漏掉了。
    但是今天我测试过了。
    同域条件下,
    我今天谷歌控制台直接运行,
    是完全正常的。没有出现报错。
    canadahetian
        23
    canadahetian  
    OP
       2020-04-14 06:07:57 +08:00
    @cydian 是这样,我已经解决了,但是没用你的方法,因为你 d 俄方法 Chrome 控制台,就报错,
    我的思路和你分享一下:

    首先我之前一直在找高度, 花费了很长时间,用 offsetTop 属性去找高度,发现不管怎么找,永远都是 0,我在 stackflow 上看到有一个人他和我用同样的方法,结果找到的却不是 0, 于是看了一下 scrollTo 方法的各版本的介绍,原来我定位的 iframe 里面的元素高度,是 A 标签,然而 A 标签里面没有给值,所以死活是找不到的.
    于是我给 A 标记的父标记,添加了一个 ID 属性(为了方便查找)

    var iframe__tag = $("#iframename").getElementsByClassName("a_class_name")

    $.each(iframe__tag , function (index, element) {

    var h_name = element.parentElement.innerText.replace(/\s+/g, "-
    ").toLowerCase().replace(/。|\.|\,|\,|\.|\:|\;|\./g, "");

    element.parentElement.id = h_idname
    // console.log(element.parentElement);

    });

    var scroll_y = $("#iframename").documentElement.getElementById(x_text).offsetTop

    window.scrollTo(0, scroll_y) //直接跳转到标签部分

    以上就是思路,感谢回复.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2718 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 15:27 · PVG 23:27 · LAX 07:27 · JFK 10:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.