Tìm hiều cách chèn hình ảnh vào đoạn văn khi viết blog



  • Mình đang làm một chức năng viết blog, nhưng mình không biết cách để hình ảnh up từ máy tính hiện bên trong văn bản mình viết theo dấu con trỏ. Tương tự như phần viết bài post của trang diễn đàn mình vậy. Mong các pro hướng dẫn góp ý



  • This post is deleted!


  • Em nghĩ là vầy:
    Client: Đang viết bài. Nhấp vào module up ảnh. Lúc này bác connect up qua API của server. Server: Dùng multer của expressjs. Sau đó lấy cái module này https://github.com/image-size/image-size. Để lấy các thông số width heigh. Sau đó server response về các thông số url, width, heigh.
    Client: Chèn vào đoạn blog đang viết chỗ con trỏ một code bác quy định (ví dụ : (img url="url" width="width" height="height") ). Rôi khi bác submit cứ gửi đầy đủ lên server lưu lại.

    • Khi ai vào đọc blog yêu cầu API gửi về trang blog bác viết. THì trước khi show ra bác quét hết response server trả về. Bác dùng JS quét hết. Kiêm coi ở đâu có (img) thì xóa đi thay bằng thẻ <img> với các thông số trên là okie roài :))). Còn làm sao đẹp thì bác tính toàn chèn thông số style sheet sao cho đẹp. Có thể viết một group css nhỏ dùng cho chèn ảnh giữa blog.


  • @Nguyen-Hien Bác có nói tới "Lúc này bác connect up qua API của server" là sao bác:



  • @tranthanh Thì bác muốn show ảnh ra cơ bản là phải có một API để up ảnh lên và lưu lại đã.

    1. Bác viết 1 Api cho phép upload ảnh lên. Em hay dùng multer.
    2. Lúc họ viết bài á. Nhấp vào cái hình up ảnh trên trang mình thì mình gửi qua API bth. Dùng thêm module trên server để lấy đủ thông số.
    3. Response server trả về mình lấy những thứ cần thiết. Chèn một dạng kí tự đặc biệt do mình quy định để hiểu là chỗ đó là chỗ show hình ảnh.
    4. Khi load một blog lúc này Server sẽ trả cho bác một đoạn text dài. Trong đó chỗ nào có cái dạng kí tự đặc biệt mà mình quy định thì xóa đi. Dùng JS thay chỗ đó thành thẻ image của HTML.
    5. Để chèn cái ảnh đẹp. Thì bác viết ra 1 cái Group CSS cho image blog như center, background ..... Dùng Js chèn cùng vào luôn. Lúc nào cũng có gọi ra nó tiện.


  • Phần server bạn có thể dùng busboy hay multer để upload => trả về đường dẫn của file vừa upload cho client. Tại client, với url của file vừa upload thì có thể dùng thẻ img của HTML hoặc dùng theo markdown theo cú pháp ở đây để hiển thị.
    Mình sẽ viết tạm một ví dụ:

    • Phần Server:
      Trc hết, tạo thư mục public để lưu trữ index.html và file upload.
    // server.js
    var express = require('express');    
    var busboy = require('connect-busboy');
    var path = require('path');
    var fs = require('fs');       
    
    var app = express();
    app.use(busboy());
    app.use(express.static(path.join(__dirname, '/public')));
    
    app.route('/upload')
        .post(function (req, res, next) {
            let fstream;
            req.pipe(req.busboy);
            req.busboy.on('file', function (fieldname, file, filename) {
                console.log("Uploading: " + filename);
                fstream = fs.createWriteStream(__dirname + '/public/' + filename);
                file.pipe(fstream);
                fstream.on('close', function () {    
                    console.log("Upload Finished of " + filename);              
                    res.json({code:'done',path:'/'+filename});
                });
            });
        });
    
    var server = app.listen(3000, function() {
        console.log('Listening on port %d', server.address().port);
    });
    
    
    • phần client:
      ở đây mình mình dùng marked.js render content của textarea.
    <!-- public/index.html -->
    <!DOCTYPE html>
    <html lang="en">
    	<head>
    		<meta charset="UTF-8">
    		<title>Simple upload</title>
    		<script type="text/javascript" src='/marked.min.js'></script>
    		<style>
    			body {font-size: 110%}
    			img {max-width: 100%;}
    		</style>
    	</head>
    	<body>
    		<div class='writePreview' style="display: flex">
    			<textarea id='blogWrite' style='height:200px;width: 50%;'>
    ## EXAMPLE UPLOAD + CURRENT CURSOR
    Saturation point marketing pistol table boat knife urban. 
    			<MOVE CURSOR HERE>
    Crypto-voodoo god tattoo smart-dissident wristwatch fluidity industrial grade Kowloon neural. 
    			</textarea>
    			<div id='mdRender' style='width: 50%; padding: 10px; border: 1px solid #f4f4f4;margin: 0 10px;'></div>
    		</div>
    		<div>
    			<form onsubmit='return false;' id='formUpload' enctype="multipart/form-data">
    				<input type='file' name='fileUpload'>
    				<button id='uploadBtn' style='background:green;color:white;border:0;padding:5px'>Upload</button>
    			</form>
    		</div>
    		<script type="text/javascript" src='/upload.js'></script>
    	</body>
    </html>
    

    mình chỉ biết viết pure javascript nên đoạn dưới này hơi dài.

    // public/upload.js
    // thêm chức năng chèn theo vị trí con trỏ vào Textarea
    HTMLTextAreaElement.prototype.insertCurrent = function(text) {
        var text = text || '';
        if (document.selection) {
            this.focus();
            var sel = document.selection.createRange();
            sel.text = text;
        } else if (this.selectionStart || this.selectionStart === 0) {
            var startPos = this.selectionStart;
            var endPos = this.selectionEnd;
            this.value = this.value.substring(0, startPos) + text + this.value.substring(endPos, this.value.length);
            this.selectionStart = startPos + text.length;
            this.selectionEnd = startPos + text.length;
        } else {
            this.value += text;
        }
    };
    // hàm lấy element
    function q(query) {
        return document.querySelector(query);
    };
    
    (function() {
        var $file = q('[name=fileUpload]');
        var $uploadBtn = q('#uploadBtn');
        var $form = q('#formUpload');
        var $blogWrite = q('#blogWrite');
        var $mdRender = q('#mdRender');
        var $http = new XMLHttpRequest();
        var render = function(){$mdRender.innerHTML = marked($blogWrite.value);}
        render();
        $blogWrite.oninput = function(){
        	return render();
        };
    
        $uploadBtn.onclick = function() {
            var file = $file.files[0];
            if (!file) return console.error('Need to choose an Image file.');
            var formData = new FormData($form);
            $http.onreadystatechange = function(event) {
                var resp = event.currentTarget.response;
                if ($http.readyState == 4) {
                    if ($http.status == 200) {
                        var content_type = $http.getResponseHeader('Content-Type');
                        if (content_type.indexOf('application/json') != -1) resp = JSON.parse(resp);
                        if (resp instanceof Object) {
                            var url = resp['path'];
                            if (!url) return;
                            var IMGTAG = '\n\n![alt text](%url "Logo Title Text 1")\n\n'.replace("%url",url);
                            $blogWrite.insertCurrent(IMGTAG);
                            return render();
                        };
                    } else {
                        console.error('Upload fail.', resp);
                    };
                }
            };
            $http.open('POST', '/upload');
            $http.send(formData);
        };
    
    })();
    

    Minh họa :
    0_1477851585479_1.png
    1_1477851585480_2.png



  • @hidemanvn Cam on bac. Nhưng bác ơi hình như ckeditor có hỗ trợ làm việc này đúng không bác


Log in to reply