月度存档: 9 月 2021

iframe父子间传值通信

父页面调用子页面方法:FrameName.window.childMethod();
子页面调用父页面方法:parent.window.parentMethod();

例子:

父页面

<html>
<head>
    <script type="text/javascript">
        function say(){
            alert("parent.html");
        }
        function callChild(){
            myFrame.window.say();
            myFrame.window.document.getElementById("button").value="调用结束";
        }
    </script>
</head>
<body>
    <input id="button" type="button" value="调用child.html中的函数say()" onclick="callChild()"/>
    <iframe name="myFrame" src="child.html"></iframe>
</body>
</html>

子页面

<html>
<head>
    <script type="text/javascript">
        function say(){
            alert("child.html");
        }
        function callParent(){
            parent.say();
            parent.window.document.getElementById("button").value="调用结束";
        }
    </script>
</head>
<body>
    <input id="button" type="button" value="调用parent.html中的say()函数" onclick="callParent()"/>
</body>
</html>

跨域 iframe 父子间传值

父页面:

<template>
    <div>
        <iframe 
         :src="iframesrc" 
         id="a-page"></iframe>
    </div>
</template>

<script>
export default {
    computed:{
        iframesrc:function(){
            let iframesrc = "http://b.com"
            return iframesrc
        }
    },
    created () {
        // 得到B传来的值 
        window.addEventListener('message',function(e){
            console.log("B DOM的高度", e.data)
        },false);
        // 监听A页面的事件,发送给B
        window.addEventListener('scroll', function () {
            let iframe = document.getElementById('a-page');

            let json = {
                scrollTop: scrollTop,
                windowHeight: windowHeight,
            };
            iframe.contentWindow.postMessage(json, '*');
        });
    }
}
</script>

子页面

<template>
    <div>
        <div id="b-page"></div>
    </div>
</template>

<script>
export default {
    mounted() {
        // 获取到B页面的值,发送给A
        let _this = this
        let b_pageH = document.getElementById('b-page').scrollHeight;
        window.parent.postMessage(b_pageH, '*');
        // 得到A页面的值
        window.addEventListener('message',function(e){
            console.log("e.data.scrollTop", e.data.scrollTop)
            console.log("e.data.windowHeight", e.data.windowHeight) 
        },false);
    }
}
</script>

结合canvas动画背景的基础布局

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>结合canvas动画背景的基础布局</title>
    <style>    
.div-relative{position:relative; color:#000; border:1px solid #000; width:500px; height:530px}    
.div-a{ position:absolute; left:30px; top:30px; background:#F00; width:400px; height:100px;z-index:10;}    
/* css注释说明: 背景为红色 */    
.div-b{ position:absolute; left:30px; top:130px; background:#FF0; width:400px; height:200px;z-index:20;}    
/* 背景为黄色 */    
.div-c{ position:absolute; left:30px; top:330px; background:#00F; width:400px; height:100px;z-index:30;}    
/* DIV背景颜色为蓝色 */   

.flexContainer {
  display: flex;
  background-color: gray;
  width: 300px;
  height: 100px;
}
.flexItem {
  width: 80px;
  height: 80px;
}
</style> 
</head>
<body>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
</script>

<div class="div-relative">   
<canvas id="myCanvas" width="500" height="530" style="border:1px solid #c3c3c3;">
您的浏览器不支持 HTML5 canvas 标签。
</canvas>
<div class="div-a">我背景为红色</div>    
<div class="div-b" id="div1">
    <iframe src="https://amyflash.com" width="400"></iframe>
  <p>您的浏览器不支持 iframes 。</p>
</iframe>
    </div>    
<div class="div-c">
    <div class="flexContainer">
    <div class="flexItem" style="background-color: red" id="b1">a</div>
    <div class="flexItem" style="background-color: blue" id="b2">b</div>
    <div class="flexItem" style="background-color: green" id="b3">c</div>
   </div>
</div>    
</div> 
<script>

$(document).ready(function(){
  $("#b1").click(function(){
   alert("段落被点击了。");
$("iframe").attr("src","https://amyflash.com/?p=2555");
  });
});

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.fillStyle="#00fff0";
ctx.fillRect(0,0,500,530);


</script>
</body>
</html>

div&canvas重叠

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>div&canvas重叠</title>
    <style>    
.div-relative{position:relative; color:#000; border:1px solid #000; width:500px; height:400px}    
.div-a{ position:absolute; left:30px; top:30px; background:#F00; width:400px; height:100px;z-index:30;}    
/* css注释说明: 背景为红色 */    
.div-b{ position:absolute; left:30px; top:40px; background:#FF0; width:400px; height:200px;z-index:20;}    
/* 背景为黄色 */    
.div-c{ position:absolute; left:30px; top:50px; background:#00F; width:400px; height:100px;z-index:10;}    
/* DIV背景颜色为蓝色 */    
</style> 
</head>
<body>



<div class="div-relative">   

    <canvas id="myCanvas" width="500" height="400" style="border:1px solid #c3c3c3;">
您的浏览器不支持 HTML5 canvas 标签。
</canvas>

<div class="div-a">我背景为红色</div>    
<div class="div-b"></div>    
<div class="div-c"></div>    


</div> 

<script>

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.fillStyle="#00fff0";
ctx.fillRect(0,0,500,400);

</script>

</body>
</html>

as3系列之loading

1.加载图片

最简单加载

var loader:Loader = new Loader();
var request:URLRequest = new URLRequest("images/flower.jpg");
loader.load(request);
//圆形遮盖
//loader.mask = masker;
addChild(loader);
loader.x = 556;
loader.y = 60;

加上基本加载进度的控制及淡入淡出效果

//淡入淡出特效
/**
greensock库地址:待补充
*/
import com.greensock.*;
import com.greensock.easing.*;
var mc:MovieClip = new MovieClip();
mc.addChild(loader);
addChild(mc);

//分别侦听图片的下载开始、下载中和下载结束事件
loader.contentLoaderInfo.addEventListener(Event.OPEN, openHandler);
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
//图片开始下载时,设置mc为完全透明,以便于设置后面的淡入动画效果
function openHandler(event:Event):void {
    mc.alpha = 0;
}
//图片下载时,不断触发progressHandler函数,刷新进度条显示
function progressHandler(event:ProgressEvent):void {
    mProgress.bar.scaleX = event.bytesLoaded/event.bytesTotal;
    mProgress.tLoadingProgress.text = Math.round(event.bytesLoaded/event.bytesTotal*100)+"%";
}
//图片下载并初始化完毕后,进度条淡出,0.5秒后图片淡入
function initHandler(event:Event):void {
    TweenLite.to(mc, 1, {alpha:1,delay:.5});
    TweenLite.to(mProgress, 1, {alpha:0});
}

可以用逐帧方式表达更逼真的缓动效果

//导入TweenLite
import com.greensock.*;
import com.greensock.easing.*;

//将图片加载到loader中,并通过mc显示到舞台
var mc:MovieClip = new MovieClip();
var loader:Loader = new Loader();
loader.load(new URLRequest("images/flower_3.jpg"));
mc.addChild(loader);
addChild(mc);
mc.x = 77;
mc.y = 203;

//分别侦听图片的下载开始、下载中和下载结束事件
loader.contentLoaderInfo.addEventListener(Event.OPEN, openHandler);
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
//图片开始下载时,设置bar元件的enterframe事件侦听
function openHandler(event:Event):void {
    mc.alpha = 0;
    mProgress.bar.scaleX = 0;
    mProgress.bar.tsx = 0;
    mProgress.bar.addEventListener(Event.ENTER_FRAME, refreshBar);
}
//图片下载过程中,bar元件的宽度以平滑方式变化
function refreshBar(event:Event):void{
    //该算法设置了一个弹性值,使bar元件的宽度变化带有缓动值,缓动程度取决于算法的分母
    mProgress.bar.scaleX += ( mProgress.bar.tsx - mProgress.bar.scaleX) / 10;
    //由于以上算法将使bar元件永远无限接近100%宽度,当bar元件的宽度缩放值大于99%时,移除enterframe事件侦听,显示图片
    if(mProgress.bar.scaleX>.99){
        mProgress.bar.removeEventListener(Event.ENTER_FRAME, refreshBar);
        showImage();
    }
}
//图片下载时,不断触发progressHandler函数,刷新bar元件的scaleX目标值
function progressHandler(event:ProgressEvent):void {
    mProgress.bar.tsx = event.bytesLoaded/event.bytesTotal;
}
//显示图片
function showImage():void {
    TweenLite.to(mc, 1, {alpha:1,delay:.5});
    TweenLite.to(mProgress, 1, {alpha:0});
}

一般加载而言,上面代码够用了,如果要自定义加载动画,精确控制加载过程以及异常处理等,参考如下代码:

import com.greensock.*;
import com.greensock.easing.*;

var mc:MovieClip = new MovieClip();
var loader:Loader = new Loader();
var urlrequest:URLRequest = new URLRequest("images/flower_5.jpg");
loader.load(urlrequest);
mc.addChild(loader);
addChild(mc);
mc.x = 67;
mc.y = 91;
mc.alpha = 0;
loader.contentLoaderInfo.addEventListener(Event.OPEN, openHandler);
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
loader.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpstatusHandler);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioerrorHandler);
loader.contentLoaderInfo.addEventListener(Event.UNLOAD, unloadHandler);
this.addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
var i:Number = 0;
var loadingProgress:Number = 0;
var frameTotal:Number = 50;
function onEnterFrameHandler(e){
    if(loadingProgress>i){
        i++;
        //mProgress为自定义动画,总共frameTotal帧
        mProgress.gotoAndStop(i);
    }
    if(i==50){
        this.removeEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
        TweenLite.to(mc, 1, {alpha:1,delay:0});
        //TweenLite.to(mProgress, 1, {alpha:0});
    }
}
function openHandler(event:Event):void {
    trace("loading begins");
}
function progressHandler(event:ProgressEvent):void {
    //mProgress.gotoAndStop();
    loadingProgress = Math.round(event.bytesLoaded/event.bytesTotal*frameTotal)
    //tLoadingProgress.text = String(Math.round(event.bytesLoaded/event.bytesTotal*100)+"%");
}
function completeHandler(event:Event):void {
    trace("loading completed");
}
function initHandler(event:Event):void {
    /*TweenLite.to(mc, 1, {alpha:1,delay:.5});
    TweenLite.to(mProgress, 1, {alpha:0});*/
    trace("width: "+event.target.content.width);
}
function httpstatusHandler(event:HTTPStatusEvent):void {
    trace("httpstatus: "+event);
}
function ioerrorHandler(event:IOErrorEvent):void {
    trace("ioerror: "+event);
}
function unloadHandler(event:Event):void {
    trace("unload");
}

2.swf文件自身加载

//首先,让文件在第一帧停止播放
stop();
//初始化txt文本框显示
txt.text = "0%";
//为文件自身注册“下载中”和“下载完毕”事件侦听
this.loaderInfo.addEventListener(Event.COMPLETE, completeHandler);
this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
//当文件正在下载时,不断触发progressHandler函数来刷新百分比进度显示
function progressHandler(event:ProgressEvent):void {
    txt.text = Math.round(event.bytesLoaded/event.bytesTotal*100)+"%";
}
//当文件下载完毕后,跳转到第二帧显示
function completeHandler(event:Event):void{
    this.gotoAndStop(2);
}

3.多文件加载

建议使用第三方库BulkLoader,好处是方便控制整体进度

import com.greensock.*;
//导入BulkLoader
import br.com.stimuli.loading.BulkLoader;
import br.com.stimuli.loading.BulkProgressEvent;
//创建一个BulkLoader对象
var bulkLoader : BulkLoader = new BulkLoader("myloader");
//向bulkLoader中添加需要加载的图片路径
for (var i:Number=0; i<8; i++) {
    bulkLoader.add("images/0"+i+".jpg", {id:"img"+i});
}
//当所有文件加载完毕时触发onAllItemsLoaded函数
bulkLoader.addEventListener(BulkLoader.COMPLETE, onAllItemsLoaded);
//当下载进行时触发onAllItemsProgress函数
bulkLoader.addEventListener(BulkLoader.PROGRESS, onAllItemsProgress);
//开始加载
bulkLoader.start();
//下载进行时,刷新百分比进度显示
function onAllItemsProgress(e : BulkProgressEvent):void {
    tLoading.text = Math.round(e.percentLoaded*100)+"%";
}
//所有图片加载完毕时,从bulkLoader中取出每张图片并显示到舞台中
function onAllItemsLoaded(e : Event):void {
    tLoading.text = "100%";
    for (var i:Number=0; i<8; i++) {
        var mc:MovieClip = new MovieClip();
        mc.x = 68+(i%4)*221;
        mc.y = 174 + Math.floor(i/4)*136;
        mc.addChild(bulkLoader.getBitmap("img"+i));
        addChild(mc);
    }
}

4.加载swf

import com.greensock.*;
//创建一个子文件的显示容器
var mc:MovieClip = new MovieClip();
var loader:Loader = new Loader();
var urlrequest:URLRequest = new URLRequest("swf/9.swf");
//加载子文件
loader.load(urlrequest);
mc.addChild(loader);
addChild(mc);
//侦听子文件的加载完毕事件
loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
//当子文件加载完毕时,从子文件第二帧开始播放动画,并淡出下载中标志
function initHandler(event:Event):void {
    event.target.content.gotoAndPlay(2);
    event.target.content.app = this;
    TweenLite.to(mRing, 1, {alpha:0});
}

4.1.父子swf的交互

加载好swf后,可以控制子swf的内容,这是父控制子;子也可以控制父;原理就是变量赋值,参考代码:

import com.greensock.*;

var mc:MovieClip = new MovieClip();
addChild(mc);

function initHandler(event:Event):void {
    event.target.content.gotoAndPlay(2);
    //设置子文件的父容器引用变量
    event.target.content.app = this;
    TweenLite.to(mRing, 1, {alpha:0});
}
function openSec(target:String) {
    mRing.alpha = 1;
    //清空mc,避免加载的子文件重叠在一起
    if (mc.numChildren>0) {
        var loop:Number = mc.numChildren;
        for (var i:Number = 0; i < loop; i++) {
            mc.removeChildAt(0);
        }
    }
    var loader:Loader = new Loader();
    //根据target参数判断加载哪个子文件
    if (target=="main") {
        loader.load(new URLRequest("swf/9_1.swf"));
    } else if (target=="sub") {
        loader.load(new URLRequest("swf/9_2.swf"));
    }
    mc.addChild(loader);
    loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
}
openSec("main");
//swf/9_1.swf的最后一帧上
stop();
bMore.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandeler);
function onMouseDownHandeler(e:MouseEvent):void{
    if(this.app){
        this.app.openSec("sub");
    }
}
//swf/9_2.swf的最后一帧上
stop();
bBack.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandeler);
function onMouseDownHandeler(e:MouseEvent):void{
    if(this.app){
        this.app.openSec("main");
    }
}

5 本地文件加载

//导入FileReference类
import flash.net.FileReference;
//创建一个FileReference对象
var fileReference:FileReference = new FileReference();
//创建一个文件类型过滤对象
var fileFilter:FileFilter = new FileFilter("文本文件","*.txt");
bBrowse.addEventListener(MouseEvent.MOUSE_DOWN, browseFile);
bClear.addEventListener(MouseEvent.MOUSE_DOWN, clearTF);

fileReference.addEventListener(Event.SELECT, onSelectFile);
fileReference.addEventListener(Event.COMPLETE,onFileComplete);
//当按下BROWSE按钮时,弹出文件对话框,供用户选择要打开的文件
function browseFile(e:MouseEvent) {
    //通过使用fileFilter来限制用户只能选择txt文本文件
    fileReference.browse([fileFilter]);
}
//当用户在文件对话框中选择某个文件后,在Flash中加载该文件
function onSelectFile(event:Event):void {
    fileReference.load();
}

//当文件加载完毕时,显示文本内容
function onFileComplete(event:Event):void {
    //在tf文本框中显示打开文件的名称
    tf.htmlText = "opening: " + fileReference.name + "<br>";
    //加载的文本数据为二进制数据,需要将其转换为GB2312编码的字符串
    var bytes:ByteArray = fileReference.data;
    //var newtext:String=fileReference.data.readMultiByte(fileReference.data.length,"gb2312");//默认是UTF-8
    //在tf文本框中显示文本内容
    tf.appendText(newtext);
}

//当按下CLEAR按钮时,清空文本显示
function clearTF(e){
    tf.text = "";   
}

6.本地图像加载

var refF:FileReference = new FileReference();
var fileFilter:FileFilter = new FileFilter("Images","*.png;*.gif;*.jpg");
var loader:Loader = new Loader();

bBrowse.addEventListener(MouseEvent.MOUSE_DOWN, browseImage);
function browseImage(e:MouseEvent):void {
    refF.browse([fileFilter]);
    refF.addEventListener(Event.SELECT,onSelectFile);
}
function onSelectFile(e:Event):void {
    refF.load();
    refF.addEventListener(Event.COMPLETE,onComplete);
    //移除refF的SELECT事件侦听
    refF.removeEventListener(Event.SELECT,onSelectFile);
}
function onComplete(e:Event):void {
    //移除refF的COMPLETE事件侦听
    refF.removeEventListener(Event.COMPLETE,onComplete);
    //使用Loader对象以二进制方式加载位图数据
    loader.loadBytes(refF.data);
    //显示图像
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoadComplete);
}
//当Loader对象的位图数据加载完毕时,显示图像
function onLoadComplete(e:Event):void {
    var pt:Point = new Point(0, 0);
    //创建一个BitmapDat位图对象,宽度和高度与所加载的位图相同,
    var tempData:BitmapData = new BitmapData(loader.width,loader.height);
    //在BitmapData中绘制位图
    tempData.draw(loader);
    //溶解位图,雪花点效果(可选)
    //tempData.pixelDissolve(tempData, tempData.rect, pt, Math.random(), 20000, 0x99FFFFFF);
    //将BitmapData位图转换为可显示的Bitmap对象
    var bitmap:Bitmap = new Bitmap(tempData);
    //将Bitmap对象显示在mHolder容器中
    mHolder.addChild(bitmap);
}

大数据平台从理论到实践8-大数据可视化工具

除了d3.js,echart等,据说还有一个牛逼的开源可视化工具-Gephi,它是一种复杂网络分析工具,应用于各种网络和复杂系统的开源软件,允许开发者扩展和重复使用

大数据平台从理论到实践7

实时用户画像系统的搭建参考:
https://www.cnblogs.com/tree1123/p/12954953.html

大数据平台从理论到实践6

关于深网,就是不能从搜索引擎搜索到的公开内容
深网里大部分数据都是从数据库里面查询出来的结构化数据

实时数据(比如log)采集流程

采集log-》flume(装载工具)->kafka->spark/storm/flink(计算引擎)->存储rdbms(Relational Database Management System)/nosql-》处理-》展示

系统日志的采集工具

facebook的scribe
hadoop平台的chukwa
cloudera公司的flume
处理效率,每秒上百兆

标签的前端管理

离线数据的可视化等功能依赖Springboot+Vue.js搭建的前后端分离系统进行展示
而Hive和Druid的可视化查询功能,我们可以用Superset这个BI工具,
superset的搭建和使用参考:https://www.jianshu.com/p/b02fcea7eb5b

大数据平台从理论到实践5

最近在做数据批量导入工作,就发现用sql的select&insert方式装载大量数据效率太低,对不同的数据库其实有不同的批量导入的优化工具,比如:

1.bcp

BCP是SQL Server中负责导入导出数据的一个命令行工具,它是基于DB-Library的,并且能以并行的方式高效地导入导出大批量的数据

2.bulk

  • 2.1、bulk相当于数据库里的bash操作。
  • 2.2、引入批量操作bulk,提高工作效率,你想啊,一批一批添加与一条一条添加,谁快?
  • 2.3、bulk API可以帮助我们同时执行多个请求
  • 2.4、bulk一次最大处理多少数据量?
      bulk会把将要处理的数据载入内存中,所以数据量是有限制的,最佳的数据量不是一个确定的数值,它取决于你的硬件,你的文档大小以及复杂性,你的索引以及搜索的负载。
      一般建议是1000-5000个文档,如果你的文档很大,可以适当减少队列,大小建议是5-15MB,默认不能超过100M,可以在es的配置文件(即$ES_HOME下的config下的elasticsearch.yml)中
    ~~~~~~

另外,关于数据的增量加载:

1.oracle cdc(changed data capture)

支持自动记录数据变化日志,可以通过比对日志进行增量加载,变化的数据会保存在db的变化表中

2.时间戳

3.md5全表扫描

4.触发器

触发器增量抽取原理:
在源数据表上建立触发器(ex可以建立插入,修改和生产三个触发器),每当源表数据变化,通过相应触发器将变化的数据写入临时表。抽取线程从临时表抽取数据。抽取过的数据被标记或者删除。优点:数据抽取性能较好;缺点:对业务建立出发器,对业务系统有影响