可配置化H5学习笔记

2020-08-05  本文已影响0人  江湖快递猫

介绍

可编辑H5页面由三个部分组成:

  1. 模板插入:根据点击不同的模板类型在页面上插入不同模板
  2. 模板排序:用户可以通过拖拽对插入的模板调整位置
  3. 模板数据:用户保存H5页面后,提取模板数据,用于渲染H5页面

模板工厂类

  1. 新建模板工厂类

    function ElementFactory(element, type){
        //存储模板数据
        this.data = {
            type:type
        }
        //存储模板的dom对象
        this.element = element
    }
    
  2. 全局变量定义

    ElementFactory.onMove      = false  // 模板是否在拖拽中
    ElementFactory.onMoveObj   = null   // 处于拖拽状态的模板对象
    ElementFactory.onChooseObj = null   // 处于选择状态的模板对象
    ElementFactory.defaultDiv  = null   // 临时对象
    
  3. 初始化模板拖拽事件

    ElementFactory.prototype.initMove = function(x, y, height){
        this.x = x
        this.y = y
        this.height = height
        this.element.style.position = 'absolute'
        this.element.style.opacity  = '0.6'
        //插入临时对象
        ElementFactory.defaultDiv = $("<div class='dash div-default'></div>");
        var height = $(this.element).height()
        //设置临时对象高度
        ElementFactory.defaultDiv.height(height)
        //将临时对象放置在拖拽对象前面
        ElementFactory.defaultDiv.insertBefore($(this.element));
    }
    
  4. 模板拖拽移动事件

    ElementFactory.prototype.move = function(x, y){
     $(this.element).css({left: x + 'px',top: y + 'px'});
    }
    
  5. 模板拖拽结束事件

    ElementFactory.moveup = function(){
        $(ElementFactory.onMoveObj.element).insertBefore(ElementFactory.defaultDiv)
        //将拖拽对象的position设置回static,使之不脱离文档流
        ElementFactory.onMoveObj.element.style.position = 'static'
        //移除临时对象
        ElementFactory.defaultDiv.remove()
        //清空拖拽中对象
        ElementFactory.onMoveObj = null
        //清空拖拽中状态
        ElementFactory.onMove = false
    }
    
  6. 模板选择事件

    ElementFactory.choose = function(element){
        //非选中模板对象初始化样式
        if (ElementFactory.onChooseObj != element && ElementFactory.onChooseObj != null) {
         ElementFactory.onChooseObj.element.style.border = "1px dashed blue"
        };
        //设置选中模板对象
        ElementFactory.onChooseObj = element
        //获取模板对象的数据
        var data = ElementFactory.onChooseObj.data
        //显示对应的工具栏
        if (data.type == 'img') {
         $('#imgTools').css('display', 'inline-block')
        };
        //选中模板时改变模板边框
        ElementFactory.onChooseObj.element.style.border = "1px solid red"
    }
    

全局变量定义

var templateArr = []//记录插入的模板
var container = document.getElementById('container')//模板容器

模板插入

使用javascript的text/template类型,当用户选择模板时插入

<script type="text/template" id="imageTemp">
    <img src="" alt="" width="100%">
</script>

图片模板插入

function addImgTemp(){
    //新建模板
    var template = document.createElement('div');
    //获取模板ID
    var id = 'template_'+Date.now()
    template.className='template-item';
    template.setAttribute('id', id)
    template.innerHTML = document.querySelector('#imageTemp').innerHTML;
    //将模板插入容器
    container.appendChild(template);
    //实例化模板并添加到模板数组
    templateArr[id] = new ElementFactory(template, 'img')
    //添加鼠标按下事件
    ....
}

模板拖拽排序

  1. 添加模板点击事件

    template.onmousedown = function (e) {
        //阻止默认事件
        e.preventDefault()
        var target = e.target
        //获取当前模板
        while(target.className != 'template-item'){
        target = $(target).parent()[0]
        }
        var id = target.getAttribute('id');
        //选中模板
        ElementFactory.choose(templateArr[id])
        //当前已有选中模板,直接释放
        if (ElementFactory.onMove) {
        ElementFactory.moveup()
        };
        var x = e.pageX - $(target).offset().left;
        var y = e.pageY - $(target).offset().top;
        //初始化模板拖拽事件
        templateArr[id].initMove(x, y, $(target).height())
        ElementFactory.onMoveObj = templateArr[id]
        ElementFactory.onMove = true
    }
    
  2. 添加模板拖拽中事件

    document.onmousemove = function (moveE) {
        //未选中模板直接返回
        if (!ElementFactory.onMove) {
            return false
        };
        var x = moveE.pageX - ElementFactory.onMoveObj.x;
        var y = moveE.pageY - ElementFactory.onMoveObj.y;
        // 拖拽元素随鼠标移动
        ElementFactory.onMoveObj.move(x, y)
        var firstTemp = $('.template-item').eq(0)
        var theDivHalf = ElementFactory.onMoveObj.height / 2
        var firstTempY = firstTemp.offset().top + theDivHalf; // 第一个元素对象的中心纵坐标
        if (y <= firstTempY) {
            ElementFactory.defaultDiv.insertBefore($('.template-item').eq(0))
        }
        //遍历模板
        $('.template-item').each(function(){
            var tarY = $(this).offset().top
            //插入临时模板
            if (y >= tarY + $(this).height()/2 && y <= tarY + $(this).height()) {
                ElementFactory.defaultDiv.insertAfter($(this));
            }
        })
        //释放模板
        this.onmouseup = function(){
            if (!ElementFactory.onMove) {
                return false
            };
            ElementFactory.moveup()
        }
    }
    

模板数据设置

以图片模板为例,选择图片时覆盖图片模板的src属性

$('#imgTools input').change(function(event) {
    var url = URL.createObjectURL(event.target.files[0])
    ElementFactory.onChooseObj.data.url = url
    $(ElementFactory.onChooseObj.element).find('img').attr('src', url)
});

保存模板数据

$('#imgTools input').change(function(event) {
    var url = URL.createObjectURL(event.target.files[0])
    //设置模板数据
    ElementFactory.onChooseObj.data.url = url
    $(ElementFactory.onChooseObj.element).find('img').attr('src', url)
});

保存数据格式

[
    {type:"img", url:url},
    {type:"img", url:url}
]

实现效果

  1. 插入两个图片模板

    插入模板
  2. 选中模板

    选中模板
  3. 选择图片

    选择图片
  4. 拖拽排序

    拖拽排序

HTML代码

<body>
    <div id="main">
        <div id="container"></div>
        <div id="tools">
            <div id="imgTools">
                <input type="file" name="" value="" placeholder="图片上传">
            </div>
        </div>
        <div id="chooseTemp">
            <div class="temp" onclick="addImgTemp()">图片</div>
        </div>
        <div id="saveBtn" onclick="save()">保存</div>
    </div>
</body>
上一篇 下一篇

猜你喜欢

热点阅读