在bootstrap模态框中使用cropper问题

求助,无法在bootstrap的模态框中cropper裁剪插件

萌新初学js与cropper插件,在模态框中无法显示使用cropper,求大佬帮忙

相关代码

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <!--Bootstrap-->
    <link rel="stylesheet" type="text/css" href="static/css/bootstrap.css">
    <!--cropper-->
    <link rel="stylesheet" type="text/css" href="static/css/cropper.css">
    <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1">
    <title>图片裁剪上传</title>
    <style type="text/css">
    .Preview {
        width: 100%;
    }
    </style>
</head>

<body>
    <form enctype="multipart/form-data" id="useravater" onsubmit="return false">
        <!--onchange中的this代指这个事件的对象-->
        <input type="file" name="file" onchange="preview(this)">
    </form>
    <!-- Modal -->
    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                    <h4 class="modal-title" id="myModalLabel">请选择合适的区域作为头像</h4>
                </div>
                <div class="modal-body">
                    <img id="uploadPreview" class="Preview" src="">
                    <div id="error_text" style="display:none"></div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                    <button type="button" class="btn btn-primary" onclick="avaterajax()">上传头像</button>
                </div>
            </div>
        </div>
    </div>
    <script type=" text/javascript" src="static\js\jquery-1.12.4.js"></script>
    <script type="text/javascript" src="static\js\bootstrap.js"></script>
    <script type="text/javascript" src="static\js\cropper.js"></script>
    <script type="text/javascript">

    var _alertMsg = document.getElementById('error_text');
    //onchange中js传参obj
    function preview(obj) {
        //onchange事件触发模态对话框
        $('#myModal').modal('show')
        //show 方法调用之后立即触发该事件
        $('#myModal').on('show.bs.modal', function(e) {
            //cropper
            $("#uploadPreview").cropper({
                aspectRatio: 1,
                crop: function(data) {
                    // Output the result data for cropping image.
                }
            });
        })

        //文件不存在直接返回
        if (obj.files.length === 0) { return; }

        var val = obj.value;
        //设定可上传的格式
        var upLoadType = '.jpg,.gif,.bmp,.png';
        //从字符串中抽出最后一次出现.之后的字符,并且转换成小写
        var fileExt = val.substr(val.lastIndexOf(".")).toLowerCase();
        //查找后缀名是否符合条件,如果符合返回>=0,如果不符合则返回负数;
        var result = upLoadType.indexOf(fileExt);

        if (result < 0) {
            _alertMsg.innerHTML = "请输入正确格式:" + upLoadType;
            _alertMsg.style.display = 'inline-block';
            document.getElementById("myModalLabel").innerHTML = "上传出现错误";
            return;
        };

        //如果只有一个文件则只需要访问这个FileList对象中的第一个元素.
        var oFile = obj.files[0];

        if (oFile.size / 1024 > 100) {
            _alertMsg.innerHTML = "请上传100k内的文件";
            _alertMsg.style.display = 'inline-block';
            document.getElementById("myModalLabel").innerHTML = "上传出现错误";
            return;
        };

        //File API提供的FileReader类型读取文件中的数据(4钟)
        var oFReader = new FileReader();

        // 当图像文件加载后,转换成一个data:URL形式保存在result属性中,最后传递到onload回调函数中
        oFReader.readAsDataURL(oFile);
        oFReader.onload = function(oFREvent) {
            document.getElementById("uploadPreview").src = oFREvent.target.result;
        };
        document.getElementById("myModalLabel").innerHTML = "请选择合适的区域作为头像";



        //hide 方法调用之后立即触发该事件
        $('#myModal').on('hidden.bs.modal', function(e) {
            //关闭模态对话框后清空file input的值
            $(obj).val('');
            //隐藏错误提示
            _alertMsg.style.display = 'none';
            //清空上次导入的图片
            document.getElementById("uploadPreview").src = '';
        })
        //$('#myModal').modal('hide')关闭
    }
    </script>
</body>

</html>
阅读 3.5k
1 个回答

首先,注意show事件和shown事件的区别:

出处
show.bs.modal show 方法调用之后立即触发该事件。如果是通过点击某个作为触发器的元素,则此元素可以通过事件的 relatedTarget 属性进行访问。
shown.bs.modal 此事件在模态框已经显示出来(并且同时在 CSS 过渡效果完成)之后被触发。如果是通过点击某个作为触发器的元素,则此元素可以通过事件的 relatedTarget 属性进行访问。

其次

出处
FileReader.onload
处理load事件。该事件在读取操作完成时触发。

也就是说当你的show回调触发的时候,$("#uploadPreview").src可能还是一个空字符串,cropper在对一个空字符串处理。你可以试试对一个没有src属性的img标签直接使用cropper。

之后你的onload事件触发,$("#uploadPreview").src被替换为选择的图片,而cropper早已完成了它的任务(对空字符串的处理),src现在变成什么cropper已经不关心了。

原因知道了,解决方法就多了,你可以自己尝试。

本人认为最合理的方法是把$("#uploadPreview").cropper()放在FileReader.onload

最后,on方法是用来绑定事件的,change也是绑定事件,按照你的逻辑,这两个方法应该同级,不应该嵌套。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题