替代废除iframe方案

废掉iframe

一 页面引进Ajax get 2

二 Shadow DOM 2

2.1 还记得iframe们吗? 2

2.2 我的名字是DOM,Shadow DOM 2

2.3 事件的情况 4

2.4 家庭作业 6

三 其他实践参考 6

3.1 【shadow dom入UI】web components思想如何应用于实际项目
6

3.2  Shadow DOM:基础 6

四 实现范例 6

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

一 页面引进Ajax get

 

$(document).ready(function(){ 

  $.get("a.html",function(data){ //初始將a.html include div#iframe

    $("#iframe").html(data);

  }); 

 

 

二 Shadow DOM

2.1 还记得iframe们吗?

   我们还在使用它们,是因为他们能确保组件和控件的JavaScript和CSS不会影响页面。 Shadow DOM 也能提供这样的保护,并且没有iframe带来的负担。正式的说法是:

Shadow DOM的设计是在shadow根下隐藏DOM子树从而提供封装机制。它提供了建立和保障DOM树之间的功能界限,以及给这些树提供交互的功能,从而在DOM树上提供了更好的功能封装。

 

如果你做过网站,那么很可能你已经用过一些JavaScript类库。既然如此,你可能会对这些不知名的类库作者心存感激。

这些作者——web开发领域的勇士们——都面对着同样的一个问题——封装。他们会花大量的精力在面向对象的经典问题之一上面,即如何封装自己的代码,以便与类库使用者的代码分离。

除了SVG,现在的Web平台只提供了一种原生的方法去隔离代码块,这并不优雅。没错,我说的就是iframe。对大部分需要封装的场景来说,frames太重而且限制太多。

如果我需要把每个自定义的按钮都放到iframe里,你是什么感觉,会不会疯掉?

所以,我们需要一些更好的东西。事实上,大部分的浏览器已经变相地提供了一种强大技术去隐藏一些实现细节。这个技术就是所谓的“shadow DOM”。

 

2.2 我的名字是DOM,Shadow DOM

 

Shadow DOM是指浏览器的一种能力,它允许在文档(document)渲染时插入一棵DOM元素子树,但是这棵子树不在主DOM树中。看一个简单的slider:

<input id="foo" type="range"/> 

把这段代码放到webkit内核的浏览器中,它会这样显示:

很简单吧,这里有一个滑槽,还有一个滑块可以沿滑槽滑动。

嗯。一切看起来都那么美好,喝杯咖啡先……等下等下,这里居然有一个可以在input元素中滑动的元素!为什么我不能通过JavaScript看到它?

var slider = document.getElementsById("foo"); 

console.log(slider.firstChild); // 返回 null 

 

2.2 这是一种魔法么?

 

我的观点来看,不是。这只是shadow DOM在起作用。你看,浏览器的开发者们已经意识到了手工编写这些DOM元素的表现和行为很困难而且很SB。所以,从一定程度上讲,他们骗了我们,给了我们一个输入框,但拥有比输入框更多的功能。

他们为你——web开发者设定了一个边界,界定了哪些是你可以访问的,哪些实现细节是访问不到的。然而,浏览器本身却可以随意跨越这个边界。设置这 样一个边界之后,它们就可以在你看不见的地方使用熟悉的web技术、同样的HTML元素去创建更多的功能,而不是像你一样要在页面上用div和span来 堆。

有一些很简单,就像上面说的slider。而有一些却相当复杂。我们来看一下video元素,它有一些按钮、进度条、hover态的音量控制,像这样:

所有的这一切都只是HTML和CSS——但是是隐藏在shadow DOM子树中的。

借用XXX的一首诗,“它是怎样工作的?”为了直观一些,我们假装可以用JavaScript操作它。看这个简单的页面:

<html> 

<head> 

<style> p { color: Green; } </style> 

</head> 

<body> 

<p>My Future is so bright</p> 

<div id="foo"></div> 

<script> 

    var foo = document.getElementById('foo'); 

    // 注意:这里只是模拟,不是真实的API 

    foo.shadow = document.createElement('p'); 

    foo.shadow.textContent = 'I gotta wear shades'; 

</script> 

</body> 

</html> 

我们获得了一个这样的DOM树:

<p>My Future is so bright</p> 

<div id="foo"></div> 

但是它像是被这样渲染出来的:

<p>My Future is so bright</p> 

<div id="foo"> <!-- shadow subtree begins --> 

    <p>I gotta wear shades</p> 

</div> <!-- shadow subtree ends --> 

看起来是这样:

注意一下,为什么渲染的句子的第二部分不是绿色的?这是因为文档(document)中选择器p不能获取到shadown DOM。很酷对不对?!如果一个框架开发者被赋予这样的能力会怎么样?想象一下你只需要写你的widget,而不用担心被不知哪里蹦出来的选择器愚弄…… 简直令人陶醉。

 

2.3 事件的情况

 

为了保持自然,shadow DOM子树中的事件可以在文档(document)中被监听。比如,你点击一下audio元素中的静音按钮,你可以在一个包裹它的div中监听到这个事件。

<div onclick="alert('who dat?')"> 

    <audio controls src="test.wav"></audio> 

</div> 

但是,如果你要确认事件的来源,会发现它是audio元素,而不是它内部的按钮。

<div onclick="alert('fired by:' + event.target)"> 

    <audio controls src="test.wav"></audio> 

</div> 

为什么这样?因为当事件穿过shadown DOM边界的时候,会被重新设定target,以避免暴露shadow DOM子树内部结构。用这种方式,你可以监听到从shadow DOM中产生的事件,而实现者也可以继续隐藏细节。

通过CSS访问(Reaching into)Shadow

另一个需要提到的技巧是怎样通过CSS来访问shadow DOM子树。假设我想自定义我的slider。我想让它有一些样式,而不是系统原生的那样,像这样:

input[type=range].custom {  

    -webkit-appearance: none;  

    background-color: Red;  

    width: 200px;  

}  

结果如下:

很好,但是我怎样定义滑块的样式呢?我们已经知道,常规的CSS选择器并不能获取到shadow DOM子树。但事实上,这里有一些很方便的伪元素,可以取到shadow DOM子树中的元素。例如,slider中的滑块在webkit中可以这样访问:

input[type=range].custom::-webkit-slider-thumb { 

    -webkit-appearance: none; 

    background-color: Green; 

    opacity: 0.5; 

    width: 10px; 

    height: 40px; 

样子如下:

很完美对不对?想想看,你可以为shadow DOM子树中的元素赋予样式,而不需要真的访问到这些元素。而这些shadow DOM的作者有了决定哪些部分可以被赋予样式的权利。如果你是作者,在做一些UI widget toolkit的时候,难道不想有这样的能力吗?

带有洞(hole)的Shadow DOM,无穷的想象力

讲完了这些令人惊叹的能力,我们想象一样,如果给一个有shadown DOM子树的元素插入子元素会怎样?我们来实验一下:

// Create an element with a shadow DOM subtree. 

var input = document.body.appendChild(document.createElement('input')); 

// Add a child to it. 

var test = input.appendChild(document.createElement('p')); 

// .. with some text. 

test.textContent = 'Team Edward'; 

结果如下:

哇!欢迎来到twilight DOM的世界!它是文档(document)的一部分,可以被遍历到,但是不会渲染!它是不是很有用呢?不一定,但是如果你需要的话它确实就在那等你。

但是,如果我们真的有能力把元素的子元素放入shadow DOM子树中会怎么样?想象一下shadow DOM是一个模板,通过它的某个洞(hole)可以看到内部的子元素:

// 注意:这里只是模拟,不是真实的API 

var element = document.getElementById('element'); 

// 创建shadow DOM子树 

element.shadow = document.createElement('div'); 

element.shadow.innerHTML = '<h1>Think of the Children</h1>' + 

    '<div class="children">{{children-go-here}}</div>'; 

// Now add some children. 

var test = element.appendChild(document.createElement('p')); 

test.textContent = 'I see the light!'; 

如果你去遍历DOM,你会看到这个:

<div id="element"> 

    <p>I see the light</p> 

</div> 

但是像是这样渲染出来的:

<div id="element"> 

    <div> <!-- shadow tree begins --> 

        <h1>Think of the Children</h1> 

        <div class="children"> <!-- shadow tree hole begins --> 

            <p>I see the light</p> 

        </div> <!-- shadow tree hole ends --> 

    </div> <!-- shadow tree ends -->  

</div> 

当你添加子元素的时候,从DOM树中看像一个正常的子元素,但是渲染的时候,他们从“洞(hole)”中进到了shadow DOM子树。

写到这里,你应该会承认,这真的很酷,也会问:

浏览器中什么时候才会有呢?

 

2.4 家庭作业

你认为听完了这么多说教的内容会没有家庭作业?作为一个JavaScript类库或者框架的开发者,尝试者去想象一下你可以利用shadow DOM制作的跟之前不一样的伟大的东西。然后想一下shadow DOM可以应用到的一些特定的使用场景(加上真实的或者模拟的代码)。

最后,共享你想到的使用场景到public-webapps邮件列表。关于在web平台中加入这种能力的讨论正在进行,我们需要你的帮助。

如果你不是一个框架作者,你仍然可以参与进来,你可以给shadown DOM加油,也可以将这份快乐传播到你最喜欢的社交网络上,因为快乐就是我们工作的全部。

附:SVG和shadow DOM

差点忘了,至于你信不信,我反正信了,SVG确实已经用到了shadow DOM,从一开始就是这样。但是比较麻烦的是,SVG的shadow DOM非常……非常……水(shady),不不,不是这个词,是另一个词,以sh开头,以y结尾。(注:对英文语境不是太熟悉,评论中有人提到是 shy。)对对,就是它!我可以继续说,但是请相信我对SVG shadow DOM的评价。或者你可以查看文档。

原文地址:http://www.toobug.net/article/what_is_shadow_dom.html

 

三 其他实践参考

  3.1 【shadow dom入UI】web components思想如何应用于实际项目

  http://www.cnblogs.com/yexiaochai/p/4167554.html

  3.2  Shadow DOM:基础

  http://www.ituring.com.cn/article/177461

 

 

四 实现范例

 

 

 

 

 

 

时间: 2024-10-02 10:35:22

替代废除iframe方案的相关文章

机顶盒项目组U盘替代NAND FLASH方案探讨

为了降低项目的产品成本,在硬件设计上选择了U盘来替代Nand Flash存储器,因此包括Linux内核及文件系统的软件需要存储在U盘中,将Uboot程序存放在SPI Flash中,使系统从U盘来启动,达到替代Nand Flash的作用. 系统要从U盘启动,首先在UBOOT中,需要能访-问U盘的文件,对于内核来说最好就是一个文件,在运行UBOOT的时候,把内核从U盘读入DDR指定地址,再把系统的控制权交给内核,即可启动内核,在内核启动的后阶段,需要挂载根文件系统,目前主要有从FLOPPY,RAMD

用JS解决网站防挂iframe木马的方案

最近公司和好朋友的网站纷纷被IFRAME了,有的挂上了鸽子,有的疯狂地弹窗,有的给人家增加流量.一个个文件去查找替换那些IFRAME代码,刚松口气,不久又加上去了.于是他们向我这个"JS高手"求救,我也不能等闲视之,只好击键杀杀杀了. 因为FF(Firefox)不怕IFRAME,于是就拿IE开刀.我只写了一句代码,就搞定了.就是IE 特有的的CSS中的属性expression,插进去试试,果然那些IFRAME不起作用了. <style type="text/css&qu

一行代码解决网站防挂IFRAME木马方案,小鸽子序列(灵儿)_应用技巧

最近公司和好朋友的网站纷纷被IFRAME了,有的挂上了鸽子,有的疯狂地弹窗,有的给人家增加流量.一个个文件去查找替换那些IFRAME代码,刚松口气,不久又加上去了,哎,什么世道!于是他们向我这个"JS高手"(他们强加给我的)求救,我也不能等闲视之,只好击键杀杀杀了. 因为FF(Firefox)不怕IFRAME,于是就拿IE开刀,不知道比尔有没有奖发.我只写了一句代码,就搞定了,哈,痛快.就是IE only(特有的)的CSS中的属性expression,插进去试试,果然那些IFRAME不

如何让iframe自适应高度.

方案一: <iframe src="http://www.alixixi.com/index.htm" name="content" id="content" allowtransparency="true" align="default" marginwidth=0 marginheight=0 frameborder=0 scrolling=no height="200″ width=&

JS实现刷新操作与选择iframe的方法

JS实现刷新操作与选择iframe的方法 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http

JavaScript中iframe实现局部刷新的几种方法汇总_javascript技巧

Iframe是一种嵌入网页的框架形式,Web页面可以通过更改嵌入的部分,达到部分内容刷新. Iframe的用法与普通的标签元素DIV类似,可以指定在页面中嵌入的位置.颜色.界面布局等 一.iframe实现局部刷新方法一 <script type="text/javascript"> $(function(){ $("#a1").click(function(){ var name= $(this).attr("name"); $(&q

凯翔:可以同时替代Nimble和Nutanix的存储

在企业级存储界,Nimble和Nutanix虽说比起EMC.IBM.NetApp来说是十足的新秀,但在国内的名气却一点也不小.而这背后的原因,在于有着软件定义存储越来越受到企业数据中心的重视.同样是初创,但有着完全国产化血统的凯翔科技,却将Nutanix和Nimble的合体作为自己的核心竞争力.  Nimble + Nutanix等于什么? 也许,若不是软件定义存储开始成为企业存储的顶梁柱,Nimble和 Nutanix之类的公司依旧会籍籍无名.软件定义存储旨在倡导通过将存储设备的数据平面和控制

javascript iframe操作与窗口调用一些方法

js操作iframe的一些知识 1. 打印iframe eg. framename.document.execcommand('print'); 2. 获取iframe eg. var ifr_window = window.frames["framename"]; 3. 获取iframe中的元素 eg1. 将iframe中id为elementid 的元素置为不显示: var ifr_window = window.frames["framename"]; ifr_

auto-comet服务器端向客户端的自动发送

介绍一个服务器端自动向客户端推送信息的框架.在这之前先要了解几个东西,首先是comet comet介绍 基于 HTTP 长连接的"服务器推"技术,是一种新的 Web 应用架构.基于这种架构开发的应用中,服务器端会主动以异步的方式向客户端程序推送数据,而不需要客户端显式的发出请求.Comet 架构非常适合事件驱动的 Web 应用,以及对交互性和实时性要求很强的应用,如股票交易行情分析.聊天室和 Web 版在线游戏等. 服务器推送技术(Server Push)是最近Web技术中最热门的一个