精华内容
下载资源
问答
  • 项目中很多地方都会用到富文本的内容:比如一般的商品详情,视频详情,资讯详情等,运营人员通过后台的富文本编辑器编辑的内容,前端拿到的就是一段富文本的字符串,这富文本大多都是图片和文字的组合。我们今天介绍...

    项目中很多地方都会用到富文本的内容:比如一般的商品详情,视频详情,资讯详情等,运营人员通过后台的富文本编辑器编辑的内容,前端拿到的就是一段富文本的字符串,这富文本大多都是图片和文字的组合。我们今天介绍的RichTextView就是一个用来加载富文本的视图

    富文本要显示出来可以使用NSAttributedString来加载通过label或者textView来显示出来,如果只是纯文字的话,直接用label和textView显示出来当然没什么问题,可是如果有图片就很麻烦了,由于是网络图片,要将图片和文字布局起来几乎很难做到

    RichTextView采用的是WebView的方式来加载富文本,将富文本当做一段html代码来加载,这样,当所有在富文本编辑器里面的css,在webview中都可以生效

    我们也知道,网页加载内容的时候,如果webView覆盖整个controller的view,可以直接设置webView的宽高和view的宽高相同,但是如果富文本的网页只是界面内容的一部分,可以是tableView的tableheaderView或者可以是tableView的某一个cell,那么我们就不得不面临一个问题,需要在内容加载完成之后将webView的高度回调回来,同时还要保证webView不会重复被加载

    如果webView中有图片,那么可以通过JavaScript注入标签的方式,将图片的url找出来,然后通过你想要展示的方式展示出来,我这里使用的是GKPhotoBrowser这个图片浏览器展示的

    RichTextView可以完全解决上面的几个问题

    demo示例图片


    950551-20181228170412554-1234245075.png950551-20181228170425983-1576131253.png950551-20181228170437325-2046606355.png950551-20181228170447358-374075847.png

    RichTextView可以很轻松解决下面问题:

    • 加载富文本字符串
    • 支持富文本中图片点击(js注入标签)
    • 加载完成返回高度
    • 图片点击放大,并能保存图片到相册
    • 提供富文本作为普通视图,TableView的TableHeaderView, TableView的Cell示例
        /// 富文本加载完成后返回高度
        var webHeight: ((_ height: CGFloat)->Void)?
    
        /// 是否允许图片点击弹出
        var isShowImage: Bool = true
    
        /// webView是否可以滚动 默认可以滚动  根据情况设置
        var isScrollEnabled: Bool = true
        
        /// 富文本内容
       var richText: String? 

    关于富文本中怎么通过JS注入标签实现图片点击并放大的功能的请参考我的往期文章: https://www.cnblogs.com/qqcc1388/p/6962895.html

    下面通过3个实际的应用场景来诠释RichTextView的用法 代码全部使用swift4.0编写 布局使用snapKit 图片显示采用GKPhotoBrowser 弹窗使用MBProgressHUD

    场景1: 全覆盖 富文本占满整个屏幕

    这种情况下设置富文本的宽高同controller的view的宽高一致,这样有一个好处就是不用太关心富文本的高度是多少了反正可以铺满整个屏幕
    一些注意点我归纳总结一下:

    • 让RichText isScrollEnabled设置为true 这样能够保证RichText能够在整个屏幕滚动
    • WebView加载富文本需要时间并不是瞬间就可以加载完成,所以当开始加载的时候可以设置一个loadingView作为遮罩,当加载完成之后移除遮罩,这样可以提升用户体验
      代码部分:
    import UIKit
    
    class RichTextDemo1VC: UIViewController{
            
        var html: String!
        
        var loadingView: LoadingView = {
            let loadingView = LoadingView()
            return loadingView
        }()
        
        override func viewDidLoad() {
            
            super.viewDidLoad()
            
            view.backgroundColor = .white
            
            html = "<p><img src=\"http://oss.hxquan.cn/bd/e0-27817083505076241.jpg\" title=\"迪丽热巴banner没有LOGO.jpg\" alt=\"迪丽热巴banner没有LOGO.jpg\"/></p><p>在2018年农历新年来临之际</p><p>火星圈&amp;Dear迪丽热巴后援会相约深圳进行春节探访</p><p>活动现场捐赠了制氧机、助行器、北京老布鞋、手绢套装等急需且贴心的物资和礼物;</p><p>和老人们在一起聊天、活动度过了愉快的时光</p><p>阿达飞奔来送上图片集锦~~</p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173692906635673.jpg\" title=\"6.jpg\" alt=\"6.jpg\"/></p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173702920452585.jpg\" title=\"1.jpg\" alt=\"1.jpg\"/></p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173712152970070.jpg\" title=\"2.jpg\" alt=\"2.jpg\"/></p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173720437853217.jpg\" title=\"3.jpg\" alt=\"3.jpg\"/></p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173731212434044.jpg\" title=\"4.jpg\" alt=\"4.jpg\"/></p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173737211482094.jpg\" title=\"5.jpg\" alt=\"5.jpg\"/></p><p><br/></p><p><br/></p><p><br/></p><p style=\"text-align: center;\"><img src=\"http://oss.hxquan.cn/bd/e0-27817539871407219.png\" title=\"可爱.png\" alt=\"可爱.png\"/></p>"
            
            demo1()
        }
        
        private func demo1(){
            //第一种情况 全覆盖 富文本占满整个屏幕
            /// 加载网页
            
            let richTextView = RichTextView(frame: view.bounds, fromVC: self)
            view.addSubview(richTextView)
            richTextView.webHeight = {[unowned self] height in
                self.loadingView .removeFromSuperview()
            }
            
            richTextView.snp.makeConstraints { (make) in
                make.edges.equalToSuperview()
            }
            richTextView.richText = html
            
            //加载loadingView
            view.addSubview(loadingView)
            loadingView.snp.makeConstraints { (make) in
                make.edges.equalToSuperview()
            }
        }
        
        deinit {
            print("RichTextDemo1VC dealloc")
        }
        
    }
    

    场景2: 富文本作为TableView的cell

    把RichText作为TableViewcell的一部分,RichText做了处理防止TableView滚动过程中webView自动load,RichText会在webView加载完成后将RichText高度回调出来,将高度缓存起来,这样就不用担心cell来回刷新导致性能不行的问题了
    一些注意点我归纳总结一下:

    • 让RichText isScrollEnabled设置为false 这样防止cell滚动过程中RichText还在滚动导致异常卡顿的情况
    • 将RichText回调的高度缓存起来
    • 注意不要造成循环引用
    • WebView加载富文本需要时间并不是瞬间就可以加载完成,所以当开始加载的时候可以设置一个loadingView作为遮罩,当加载完成之后移除遮罩,这样可以提升用户体验

    代码部分:

    
    import UIKit
    
    class RichTextDemo2VC: UIViewController{
        
        private var richTextView: RichTextView!
        
        private var html: String!
        
        private var webHeight: CGFloat = 0
        
        private var loadingView: LoadingView = {
            let loadingView = LoadingView()
            return loadingView
        }()
        
        lazy var tableView: UITableView = {
            let tableView = UITableView(frame: .zero, style: .plain)
            tableView.showsVerticalScrollIndicator = false
            tableView.showsHorizontalScrollIndicator = false
            tableView.delegate = self
            tableView.dataSource = self
            if #available(iOS 11.0, *) {
                tableView.contentInsetAdjustmentBehavior = .never
            }
            tableView.estimatedSectionHeaderHeight = 0
            tableView.estimatedSectionFooterHeight = 0
            
            tableView.tableFooterView = UIView()
            
            tableView.rowHeight = UITableView.automaticDimension;
            tableView.estimatedRowHeight = 44;
            return tableView
        }()
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            view.backgroundColor = .white
    
            html = "<p><img src=\"http://oss.hxquan.cn/bd/e0-27817083505076241.jpg\" title=\"迪丽热巴banner没有LOGO.jpg\" alt=\"迪丽热巴banner没有LOGO.jpg\"/></p><p>在2018年农历新年来临之际</p><p>火星圈&amp;Dear迪丽热巴后援会相约深圳进行春节探访</p><p>活动现场捐赠了制氧机、助行器、北京老布鞋、手绢套装等急需且贴心的物资和礼物;</p><p>和老人们在一起聊天、活动度过了愉快的时光</p><p>阿达飞奔来送上图片集锦~~</p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173692906635673.jpg\" title=\"6.jpg\" alt=\"6.jpg\"/></p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173702920452585.jpg\" title=\"1.jpg\" alt=\"1.jpg\"/></p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173712152970070.jpg\" title=\"2.jpg\" alt=\"2.jpg\"/></p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173720437853217.jpg\" title=\"3.jpg\" alt=\"3.jpg\"/></p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173731212434044.jpg\" title=\"4.jpg\" alt=\"4.jpg\"/></p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173737211482094.jpg\" title=\"5.jpg\" alt=\"5.jpg\"/></p><p><br/></p><p><br/></p><p><br/></p><p style=\"text-align: center;\"><img src=\"http://oss.hxquan.cn/bd/e0-27817539871407219.png\" title=\"可爱.png\" alt=\"可爱.png\"/></p>"
            
            demo2()
        }
        
        private func demo2(){
            
            //第二种情况 富文本作为cell的一部分
            view.addSubview(tableView)
            //设置tableView约束 安全区域
            tableView.snp.makeConstraints { (make) in
                if #available(iOS 11.0, *) {
                    make.edges.equalTo(self.view.safeAreaLayoutGuide.snp.edges)
                }else{
                    make.edges.equalToSuperview()
                }
            }
            //由于webView加载需要时间 所以可以在webView加载期间 在界面设置一个loadingView遮挡 当webview加载完无论成功或者失败都会在回调方法中关闭所谓的遮罩,这样可能会给用户一个更好的使用体验
            view.addSubview(loadingView)
            loadingView.snp.makeConstraints { (make) in
                make.edges.equalToSuperview()
            }
        }
        
        deinit {
            print("RichTextDemo2VC dealloc")
        }
    }
    
    
    extension RichTextDemo2VC: UITableViewDelegate,UITableViewDataSource{
        
        func numberOfSections(in tableView: UITableView) -> Int {
            return 1
        }
        
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 10
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            if indexPath.row == 0{
                var cell = tableView.dequeueReusableCell(withIdentifier: "customCell")
                if cell == nil {
                    cell = UITableViewCell(style: .default, reuseIdentifier: "customCell")
                    cell?.selectionStyle = .none
                    let richTextView = RichTextView(frame: .zero, fromVC: self)
                    richTextView.webHeight = { [unowned self] height in
                        self.webHeight = height
                        self.loadingView .removeFromSuperview()
                        self.tableView.reloadData()
                    }
                    //放在cell中不要让webView滚动
                    richTextView.isScrollEnabled = false
                    richTextView.richText = html
                    cell?.contentView.addSubview(richTextView)
                    richTextView.snp.makeConstraints { (make) in
                        make.edges.equalToSuperview()
                    }
                }
                return cell!
            }
            
            var cell = tableView.dequeueReusableCell(withIdentifier: "cell")
            if cell == nil {
                cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
                cell?.selectionStyle = .none
            }
            cell?.textLabel?.text = "jkdlsfkjsld"
            return cell!
        }
        
        func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
            if indexPath.row == 0 {
                return self.webHeight
            }
            return UITableView.automaticDimension
        }
        
    }
    
    

    场景2: 富文本作为TableView的tableheaderView的一部分

    将富文本作为TableViewHeaderView的一部分,这种场景的使用频率特别高,典型的像今日头条资讯详情部分,像一般商场app商品详情部分大都是在TableView的TableHeaderView中嵌套webView
    一些注意点我归纳总结一下:

    • RichText加载完成后需要重试header的高度,并且重设self.tableView.tableHeaderView = self.headerView
    • 设置TableView的header高度部分我这里用的是利用约束自适应高度,如果你也是这种方法设置的,请注意设置完约束后一定要调用一次self.headerView.layoutIfNeeded()方法让高度生效
    • RichText嵌入到Header中,RichText原本高度默认设置为0,只有当RichText加载ok才会通过约束设置RichText的真实高度,header传递出去的高度应该是RichText的高度+header中其它控件的高度
    • 让RichText isScrollEnabled设置为false 防止多重滚动的问题
            richView.webHeight = { [unowned self] height in
                
                // 将高度传递出去 RichText高度+header中其它控件高度
                self.headerHeight?(self.height+height)
            }
    • RichText本身带有防止webview重复加载的,所以不用担心性能问题
    • WebView加载富文本需要时间并不是瞬间就可以加载完成,所以当开始加载的时候可以设置一个loadingView作为遮罩,当加载完成之后移除遮罩,这样可以提升用户体验

    代码部分:

    import UIKit
    
    class RichTextDemo3VC: UIViewController{
        
        var html: String!
        
        var webHeight: CGFloat = 0
    
        lazy var tableView: UITableView = {
            let tableView = UITableView(frame: .zero, style: .plain)
            tableView.showsVerticalScrollIndicator = false
            tableView.showsHorizontalScrollIndicator = false
            tableView.delegate = self
            tableView.dataSource = self
            if #available(iOS 11.0, *) {
                tableView.contentInsetAdjustmentBehavior = .never
            }
            tableView.estimatedSectionHeaderHeight = 0
            tableView.estimatedSectionFooterHeight = 0
            
            tableView.tableFooterView = UIView()
            
            tableView.rowHeight = UITableView.automaticDimension;
            tableView.estimatedRowHeight = 44;
            return tableView
        }()
        
        lazy var headerView: RichTextHeaderView = {
            let header = RichTextHeaderView(frame: .zero, fromVC: self)
            header.headerHeight = { [unowned self] height in
                //重新设置headerHeight
                
                self.headerView.height = height
                //注意这里一定要重新设置一次tableHeaderView
                self.tableView.tableHeaderView = self.headerView
                self.loadingView.removeFromSuperview()
            }
            return header
        }()
        
        private var loadingView: LoadingView = {
            let loadingView = LoadingView()
            return loadingView
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            
            view.backgroundColor = .white
    
            //设置UI
            view.addSubview(tableView)
            tableView.snp.makeConstraints { (make) in
                if #available(iOS 11.0, *) {
                    make.edges.equalTo(self.view.safeAreaLayoutGuide.snp.edges)
                }else{
                    make.edges.equalToSuperview()
                }
            }
            
            tableView.tableHeaderView = self.headerView
            self.headerView.snp.makeConstraints({ (make) in
                make.width.equalToSuperview()
                make.top.left.right.equalToSuperview()
            })
            self.headerView.layoutIfNeeded()
            
            view.addSubview(loadingView)
            loadingView.snp.makeConstraints { (make) in
                make.edges.equalToSuperview()
            }
            
            let html = "<p><img src=\"http://oss.hxquan.cn/bd/e0-27817083505076241.jpg\" title=\"迪丽热巴banner没有LOGO.jpg\" alt=\"迪丽热巴banner没有LOGO.jpg\"/></p><p>在2018年农历新年来临之际</p><p>火星圈&amp;Dear迪丽热巴后援会相约深圳进行春节探访</p><p>活动现场捐赠了制氧机、助行器、北京老布鞋、手绢套装等急需且贴心的物资和礼物;</p><p>和老人们在一起聊天、活动度过了愉快的时光</p><p>阿达飞奔来送上图片集锦~~</p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173692906635673.jpg\" title=\"6.jpg\" alt=\"6.jpg\"/></p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173702920452585.jpg\" title=\"1.jpg\" alt=\"1.jpg\"/></p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173712152970070.jpg\" title=\"2.jpg\" alt=\"2.jpg\"/></p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173720437853217.jpg\" title=\"3.jpg\" alt=\"3.jpg\"/></p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173731212434044.jpg\" title=\"4.jpg\" alt=\"4.jpg\"/></p><p><img src=\"http://oss.hxquan.cn/bd/e0-28173737211482094.jpg\" title=\"5.jpg\" alt=\"5.jpg\"/></p><p><br/></p><p><br/></p><p><br/></p><p style=\"text-align: center;\"><img src=\"http://oss.hxquan.cn/bd/e0-27817539871407219.png\" title=\"可爱.png\" alt=\"可爱.png\"/></p>"
            
            headerView.html = html
        }
        
        deinit {
            print("RichTextDemo3VC dealloc")
        }
    }
    
    extension RichTextDemo3VC: UITableViewDelegate,UITableViewDataSource{
        func numberOfSections(in tableView: UITableView) -> Int {
            return 1
        }
        
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 20
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            var cell = tableView.dequeueReusableCell(withIdentifier: "cell")
            if cell == nil {
                cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
                cell?.selectionStyle = .none
            }
            cell?.textLabel?.text = "xxx"
            return cell!
        }
    }
    
    import UIKit
    
    class RichTextHeaderView: UIView {
    
        /// 回调header的高度
        var headerHeight: ((_ height: CGFloat)->Void)?
        
        var html: String?{
            didSet{
                richTextView.richText = html
            }
        }
        
        //MARK:- 屏幕宽高
        private let SCREEN_WIDTH = UIScreen.main.bounds.size.width
        
        private weak var currentVc: UIViewController?
        
        lazy var imgView: UIImageView = {
            let imgView = UIImageView()
            imgView.layer.cornerRadius  = 16
            imgView.layer.masksToBounds = true
            imgView.image = UIImage(named: "defaultavatar")
            return imgView
        }()
        
        lazy var nameLabel: HXQLabel = {
            let nameLabel = HXQLabel(text: "小屁股嘟嘟嘟")
            return nameLabel
        }()
        
        lazy var timeLabel: HXQLabel = {
            let timeLabel = HXQLabel(text: "2017.02.10. 10:20", color: UIColor.lightGray ,font: UIFont.systemFont(ofSize: 11))
            return timeLabel
        }()
        
        lazy var attentionBtn: HXQButton = {
            let button = HXQButton(title: "+ 关注", color: .red){[unowned self] button in
                //关注事件
            }
            button.layer.cornerRadius = 13.5
            button.layer.masksToBounds = true
            button.layer.borderColor = UIColor.red.cgColor
            button.layer.borderWidth = 1.0
            return button
        }()
        
        lazy var titleLabel: HXQLabel = {
            let label = HXQLabel(text: "爱豆防弹少年团站在此发起“0元启动0218郑号锡生日 爱豆APP开屏应援”活动。", font: UIFont.systemFont(ofSize: 16), lines: 0)
            label.numberOfLines = 0;
            return label
        }()
        
        lazy var richTextView: RichTextView = {
            let richView = RichTextView(frame: .zero, fromVC: currentVc)
            //不让网页滚动
            richView.isScrollEnabled = false
            // 网页加载完成回调网页高度
            richView.webHeight = { [unowned self] height in
                
                // 将高度传递出去 RichText高度+header中其它控件高度
                self.headerHeight?(self.height+height)
            }
            return richView
        }()
        
        /// 点赞按钮
        private lazy var praiseBtn: HXQButton = {
            let button = HXQButton(title: "点赞", color: .red, font: UIFont.systemFont(ofSize: 16)){ btn in
                btn.isSelected = !btn.isSelected
            }
            button.layer.borderColor = UIColor.lightGray.cgColor
            button.layer.borderWidth = 1.0;
            button.layer.cornerRadius = 18
            button.setImage(UIImage(named: "circle_icon_thumbup_default"), for: .normal)
            button.setImage(UIImage(named: "circle_icon_thumbup_select"), for: .selected)
            return button
        }()
        
        /// 点赞数量
        private lazy var praiseLabel: HXQLabel = {
            let label = HXQLabel(text: "4563人点赞", color: .gray, font: UIFont.systemFont(ofSize: 14))
            return label
        }()
        
        convenience init(frame: CGRect, fromVC currentVc: UIViewController? = nil) {
            self.init()
            self.currentVc = currentVc
            setupUI()
        }
        
        override init(frame: CGRect) {
            super.init(frame: frame)
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        private func setupUI(){
            addSubview(imgView)
            addSubview(nameLabel)
            addSubview(timeLabel)
            addSubview(attentionBtn)
            addSubview(titleLabel)
            addSubview(richTextView)
            addSubview(praiseBtn)
            addSubview(praiseLabel)
            
            imgView.snp.makeConstraints { (make) in
                make.left.equalTo(15)
                make.size.equalTo(CGSize(width: 32, height: 32))
                make.top.equalTo(15)
            }
            nameLabel.snp.makeConstraints { (make) in
                make.top.equalTo(imgView)
                make.left.equalTo(imgView.snp.right).offset(5)
            }
            timeLabel.snp.makeConstraints { (make) in
                make.bottom.equalTo(imgView)
                make.left.equalTo(nameLabel.snp.left)
            }
            attentionBtn.snp.makeConstraints { (make) in
                make.centerY.equalTo(imgView)
                make.right.equalTo(-20)
                make.size.equalTo(CGSize(width: 65, height: 27))
            }
            
            let line = HXQView()
            line.backgroundColor = UIColor.lightGray
            addSubview(line)
            line.snp.makeConstraints { (make) in
                make.left.equalTo(15)
                make.right.equalTo(-15)
                make.height.equalTo(1)
                make.top.equalTo(imgView.snp.bottom).offset(18)
            }
            
            titleLabel.snp.makeConstraints { (make) in
                make.left.equalTo(15)
                make.right.equalTo(-15)
                make.top.equalTo(line.snp.bottom).offset(15)
            }
            titleLabel.preferredMaxLayoutWidth = SCREEN_WIDTH - 30;
            
            richTextView.snp.makeConstraints { (make) in
                make.left.equalTo(15)
                make.right.equalTo(-15)
                make.top.equalTo(titleLabel.snp.bottom).offset(10)
            }
            praiseBtn.snp.makeConstraints { (make) in
                make.centerX.equalToSuperview()
                make.top.equalTo(richTextView.snp.bottom).offset(32)
                make.size.equalTo(CGSize(width: 93, height: 36))
            }
            
            praiseLabel.snp.makeConstraints { (make) in
                make.centerX.equalToSuperview()
                make.top.equalTo(praiseBtn.snp.bottom).offset(8)
                make.bottom.equalTo(-10)
            }
        }
    }
    

    demo下载

    更多详细内容请参考demo
    https://github.com/qqcc1388/RichTextDemo

    转载请标注来源:https://www.cnblogs.com/qqcc1388/p/10191467.html

    转载于:https://www.cnblogs.com/qqcc1388/p/10191467.html

    展开全文
  • tp3.2整合ueditor富文本编辑器

    千次阅读 2017-06-12 21:29:51
    tp3.2整合ueditor富文本编辑器

    在项目里做文章管理时,使用富文本编辑器比较方便,主要是多图片上传比较方便,第一次使用,感觉无从下手,这里记录一下我的方法

    1.首先就是去官网下载对应的php版本的富文本编辑器,这里使用的是1.4.3.2 php版本

    2.将下载的文件解压之后,将文件名改为Ueditor,放在项目里,我放在了Public文件夹下



    3.然后到view文件下的要使用富文本编辑器的页面进行初始化(引入js文件,进行设置),这里UE.getEditor 中的 info 就是 textarea的id名称


    到这里就初始化完成了,到页面刷新就会看到富文本编辑器的框框


    4.如果你是在本机上没有设置站点的情况下进行测试,编辑器已经可以使用了,因为富文本编辑的图片默认的保存地址是自动创建的,而且创建的位置是和你的项目同级的位置

    5.当你要把项目上传到服务器之后,你会发现保存图片出现问题了,这是因为保存图片的文件夹在项目外面,图片就添加不上,这时就需要修改富文本编辑的配置,找到config.json文件,如图位置


    打开配置文件,找到imageUrlPrefix,填写你的域名,这样保存图片的文件夹就建在了项目里面,而不是和项目同级的位置,这样图片就可以上传成功了。(保存图片的文件夹是自动创建的)


    这里需要注意的是,富文本编辑器保存的时候是连标签一起存进数据库的,所以查询数据库之后显示在页面时需要对内容进行处理,使用:htmlspecialchars_decode(),如图


    我设置的比较简单,传图片和内容都没有问题,网上也有很多设置方法,serverUrl好像也可以,但是我没有亲测过,感觉那个比较麻烦,本人也是新人一枚,还在编程的道路中摸索,这里也希望大神能指点一二!

    展开全文
  • 你梦想的富文本编辑器是功能齐全,配置简单,和rails兼容性好,并且在项目里使用几乎不要多余的代码,比如上传图片,视频等等不用写一行代码,自动都帮你统统搞定.你不是在做梦,Kindeditor可以满足上面所有的要求!不过在...

    rails里有很多富文本编辑器可用,比如百度编辑器,FCKEditor,CKEditor等等.不过其中有些不是功能太简单,就是配置其他太麻烦,要不然就是和Rails兼容性太差.

    你梦想的富文本编辑器是功能齐全,配置简单,和rails兼容性好,并且在项目里使用几乎不要多余的代码,比如上传图片,视频等等不用写一行代码,自动都帮你统统搞定.

    你不是在做梦,Kindeditor可以满足上面所有的要求!不过在最新的turbolinks下使用起来坑还是蛮多的,不过经过大半天的努力,终于可以比较完美的在项目中使用了.下面本猫就来造福大众,聊聊如何避开这些坑使用Kindeditor.

    我的环境是rails 4.0.6 + turbolinks 5.0.1,为什么要特的提到turbolinks的版本,因为坑主要都在turbolinks里.

    Kindeditor的官方github地址在下面:

    https://github.com/Macrow/rails_kindeditor

    安装Kindeditor很简单,只需在Gemfile里添加一行:

    gem 'rails_kindeditor'

    配置起来也很简单,也只需一行:

    rails g rails_kindeditor:install

    然后你可以按需修改config/initializers/rails_kindeditor.rb中的参数,比如上传路径,支持的上传文件后缀等等.

    RailsKindeditor.setup do |config|
    
      # Specify the subfolders in public directory.
      # You can customize it , eg: config.upload_dir = 'this/is/my/folder'
      config.upload_dir = 'uploads'
    
      # Allowed file types for upload.
      config.upload_image_ext = %w[gif jpg jpeg png bmp]
      config.upload_flash_ext = %w[swf flv]
      config.upload_media_ext = %w[swf flv mp3 wav wma wmv mid avi mpg asf rm rmvb]
      config.upload_file_ext = %w[doc docx xls xlsx ppt htm html txt zip rar gz bz2]
    
      # Porcess upload image size
      # eg: 1600x1600 => 800x800
      #     1600x800  => 800x400
      #     400x400   => 400x400  # No Change
      # config.image_resize_to_limit = [800, 800]
    
      # if you have config in your rails application like this:
      # /config/enviroments/production.rb
      #   # config.action_controller.asset_host = "http://asset.example.com"
      #   # config.assets.prefix = "assets_prefx"
      # then you should:
      #
      # config.asset_url_prefix = "http://asset.example.com/assets_prefx/" if Rails.env.production?
    
    end

    在View中嵌入Kindeditor编辑器也很简单,有很多种方法和可选项,其中一种方式如下:

    <%= kindeditor_tag :content,"亲,请告诉我们详细信息,如果能贴上示意图片那就更好了呢 ;)" %>

    然后你就会在运行的web中看到:

    这里写图片描述

    好了,简单的就这么多了,下面的坑要来了 ;(

    在rails中如果开启turbolinks(默认都是开启的,不知道turbollinks为何物的请自行谷歌),在某些时候(注意,是某些时候,其他时候又正常)会出现第一次打开页面Kindeditor被显式为text_area的情况,当你再次刷新页面时才会正确显式,为了确认这是由turbolinks引起的,你可以在整个项目中关闭turbolinks.打开application.js,将其中的以下一行删除:

    //= require turbolinks

    然后再试,你会发现页面第一次打开时可以正确显式Kindeditor控件了.

    但是全局关闭turbolinks也不是太好,因为它有一个提速的功能,是一个优化项,所以一般我们并不希望turbolinks被关掉.

    网上搜了下,大体都是采用某个页面关闭turbolinks的方法,有以下几种:

    第一种方法:
    给link_to添加一个’data-no-turbolink’ => true参数

    第二种方法:
    在application.html.erb的body中html元素中添加data-turbolink=”false”参数

    第三种方法:
    类似于前两种类型,但是在turbolinks5中参数名不一样,不是data-no-turbolinks,在stack overflow里面,可以看到各种说法,到turbolinks的官方github中也自有一套说法.

    第四种方法:
    写js或coffee脚本,在页面加载完毕后再手动加载Kindeditor,要根据Kindeditor控件的实际id来写代码.

    你会问上面这么多方法到底用哪个???

    答案是:上面四种方法在turbolinks5中没有一个管用 ;(

    别问我是怎么知道的,都是一点点试出来的…遇到各种奇怪的现象,页面时而正常,时而不正常;时而运行onload,时而不运行…满满的都是泪

    而且上述Kindeditor第一次无法正确加载的问题在一个项目中出现,在另一个项目中却压根没有,配置找不到神马差异,真是让人蛋疼…

    那么最终解决方案到底存在么!?答案是肯定的,也很简单,你只需在app/assets/javascripts中创建一个新文件load_kindeditor.coffee,然后贴入如下内容:

    # coffeescript code
      $(document).on 'turbolinks:before-cache', ->
        KindEditor.remove('.rails_kindeditor')
    
      $(document).on 'turbolinks:load', ->
        $('.rails_kindeditor').each ->
          KindEditor.create "##{$(this).attr('id')}", "allowFileManager": true, "uploadJson": $(this).data('upload'), "fileManagerJson": $(this).data('filemanager'), "width": '100%', "height": '300'

    如果你用的是Kindeditor简单模式,你可能要换成如下内容:

    # coffeescript code
      $(document).on 'turbolinks:before-cache', ->
        KindEditor.remove('.rails_kindeditor')
    
      $(document).on 'turbolinks:load', ->
        $('.rails_kindeditor').each ->
          KindEditor.create "##{$(this).attr('id')}", "allowFileManager": true, "uploadJson": $(this).data('upload'), "fileManagerJson": $(this).data('filemanager'), "width": '100%', "height": '300', "items":["fontname","fontsize","|","forecolor","hilitecolor","bold","italic","underline","removeformat","|","justifyleft","justifycenter","justifyright","insertorderedlist","insertunorderedlist","|","emoticons","image","link"]

    请确保以上文件被app/assets/javascripts/application.js正确加载!!!

    这些一切OK了 ;)

    最后如果你要在实际生成环境中部署Kindeditor,你需要运行如下命令:

    rails kindeditor:assets

    因为Kindeditor是国人开发的控件,所以在国外论坛反而不太能搜到使用方法,这也是本猫花了这么长时间才搞定的原因!

    so,good luck!!!!!

    展开全文
  • 百度富文本编辑器ueditor

    千次阅读 2019-03-24 15:39:19
    百度富文本编辑器ueditor 在日常工作用,肯定有用到富文本编辑器的时候,富文本编辑器功能强大使用方便,我用的是百度富文本编辑器,首先需要下载好百度编辑器的demo, 然后创建ueditor.html文件,引入百度编辑器,然后...

     

    百度富文本编辑器ueditor

    在日常工作用,肯定有用到富文本编辑器的时候,富文本编辑器功能强大使用方便,我用的是百度富文本编辑器,首先需要下载好百度编辑器的demo

    然后创建ueditor.html文件,引入百度编辑器,然后在html文件内引入,然后再用js实例化编辑器即可,代码如下:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    <!DOCTYPE html>

    <html>

    <head>

    <title>百度编辑器</title>

    </head>

    <body>

        <script type="text/javascript" charset="utf-8" src="ueditor/ueditor.config.js"></script>

        <script type="text/javascript" charset="utf-8" src="ueditor/ueditor.all.min.js"></script>

        <script type="text/javascript" charset="utf-8" src="ueditor/lang/zh-cn/zh-cn.js"></script>

        <script id="editor" type="text/plain" name="gdesc" style="width:100%;height:350px;"></script>

        <script type="text/javascript">

            //实例化编辑器

            var ue = UE.getEditor('editor', {});

        </script>

    </body>

    </html>

    到这里在浏览器打开上面的ueditor.html文件就能看到如下图所示:

    这是实例化后的初始编辑器,里面的功能有很多,其中有一部分可能是我们完全用不到的,想定制怎么办呢?别捉急,百度提供了可以定制的功能,将上面实例化编辑器的js代码改为以下代码:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    <script type="text/javascript">

        //实例化编辑器

        var ue = UE.getEditor('editor', {

        toolbars: [

            [

                'undo'//撤销

                'bold'//加粗

                'underline'//下划线

                'preview'//预览

                'horizontal'//分隔线

                'inserttitle'//插入标题

                'cleardoc'//清空文档

                'fontfamily'//字体

                'fontsize'//字号

                'paragraph'//段落格式

                'simpleupload'//单图上传

                'insertimage'//多图上传

                'attachment'//附件

                'music'//音乐

                'inserttable'//插入表格

                'emotion'//表情

                'insertvideo'//视频

                'justifyleft'//居左对齐

                'justifyright'//居右对齐

                'justifycenter'//居中对

                'justifyjustify'//两端对齐

                'forecolor'//字体颜色

                'fullscreen'//全屏

                'edittip '//编辑提示

                'customstyle'//自定义标题

                'template'//模板

                 ]

            ]

        });

    </script>

    刷新ueditor.html页面你就会看到变化了:

    想定制什么功能,只需要参照上面下载的编辑器demo内的ueditor.config.js文件中toolbars属性,将对应的字符串添加进去即可:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    //工具栏上的所有的功能按钮和下拉框,可以在new编辑器的实例时选择自己需要的重新定义

    , toolbars: [[

        'fullscreen''source''|''undo''redo''|',

        'bold''italic''underline''fontborder''strikethrough''superscript''subscript''removeformat''formatmatch''autotypeset''blockquote''pasteplain''|''forecolor''backcolor''insertorderedlist''insertunorderedlist''selectall''cleardoc''|',

        'rowspacingtop''rowspacingbottom''lineheight''|',

        'customstyle''paragraph''fontfamily''fontsize''|',

        'directionalityltr''directionalityrtl''indent''|',

        'justifyleft''justifycenter''justifyright''justifyjustify''|''touppercase''tolowercase''|',

        'link''unlink''anchor''|''imagenone''imageleft''imageright''imagecenter''|',

        'simpleupload''insertimage''emotion''scrawl''insertvideo''music''attachment''map''gmap''insertframe''insertcode''webapp''pagebreak''template''background''|',

        'horizontal''date''time''spechars''snapscreen''wordimage''|',

        'inserttable''deletetable''insertparagraphbeforetable''insertrow''deleterow''insertcol''deletecol''mergecells''mergeright''mergedown''splittocells''splittorows''splittocols''charts''|',

        'print''preview''searchreplace''drafts''help'

    ]]

    ueditor.config.js文件可以定制编辑器的很多功能,只需要将对应属性前面的'//'去掉,true为开启,false为关闭进行设置即可.比如:

    1

    2

    3

    4

    5

    6

    //elementPathEnabled

    //是否启用元素路径,默认是显示

    ,elementPathEnabled : false<br>

    //wordCount

    ,wordCount:false          //是否开启字数统计

    //,maximumWords:10000       //允许的最大字符数<br><br>

          // 是否自动长高,默认true
         ,autoHeightEnabled:false

    按照上面代码修改完ueditor.config.js文件,刷新页面你会看到不一样的地方:

    下面的元素路径和字数统计都消失了,是不是更加美观了呢O(∩_∩)O~

    实际应用时我们还有可能在一个域名下上传百度编辑器编辑的内容(例如:在www.52lnamp.com域名下上传了一张图片),而需求不单单是要在这域名下展示,还需要可以在其它域名下展示,这时就会出现图片不存在的情况,

    这是因为百度编辑器的配置文件中默认的上传路径是相对路径,也就是说上面上传的图片的地址是相对于当前的域名进行上传的,只有在你上传的域名下可以展示,其它域名是显示不出来的,

    如果要在另外一个域名上展示的话只需要修改配置文件为绝对路径就可以了,打开上面下载的demo,找到php/config.json文件,打开后你会看到

    其中imageUrlPrefix这个属性加上域名即可:"imageUrlPrefix": "http://www.xxx.com", /* 图片访问路径前缀 */

    需要注意的是添加域名的时候必须带上http or https,只有这样写出来的才能正常显示,不加的话在你引用的时候会在前面重复加上一个域名,基本了解了这些足以应对日常的需求,有其它另类的需求可以参考百度编辑器文档

     

     

     

    展开全文
  • 本文主要分享基于Angular和Slate开发富文本编辑器的实践历程,基于Angular做编辑器对我们来说也是一个新的尝试,社区关于Angular编辑器的实现更多的是基于原生编辑器组件化包装(比如基于Quill、Prosemirror的...
  • TextView/EditText显示GIF图片富文本 由于产品要求,app的对话页面中,需要让对话页面中显示动态的gif表情 我查询了一些资料,已找到了很好的解决方案,并编写了GifEmoticonHelper工具类. 具体Demo项目我已上传github,...
  • tinymce 富文本编辑器 每次查看详情内容不更新问题

    千次阅读 多人点赞 2019-11-21 16:37:43
    当tinymce 富文本编辑器放弹窗时 只有第一次打开弹窗的时候有初始化tinymce.init(); 后面再次查看列表详情的时候打开痰喘没有初始化数据,所以 ,富文本编辑器的组件要让它v-if销毁与重建 就可以每次都重新初始化...
  • 百度ueditor富文本--自定义插件按钮

    万次阅读 2017-08-10 16:43:13
    我们在在之前的文章中讲了 百度ueditor富文本 的 配置和初始化的方法。百度ueditor富文本--PC端单个,PC端多个,mobile单个,mobile多个我们可以给它配置更多的插件,全部插件可参考官网:...
  • 今天使用富文本的时候,客户有个需求,需要在文段的前面空两格达到缩进效果 一开始我用了两种办法 1.文字前加空格(空格源码为&nbsp;小程序前端不会有渲染效果) 2.开启ckeditor的Outdent和Indent减小缩进和...
  • 小程序富文本编辑器的问题

    万次阅读 2017-08-17 22:41:49
    今天做小程序开发时,用到百度富文本编辑器上传的图文数据,在小程序端取数据要把html格式转化.再网上搜了一波.找到这个地址: https://github.com/icindy/wxParse ----------网上有很多使用教程,不多说,要说的是...
  • Vue 自定义富文本编辑器 tinymce 支持导入 word 模板

    万次阅读 热门讨论 2018-09-13 10:03:10
    自定义富文本编辑器分为前端项目和后端项目两个部分,首先先说一下前端项目 前端 前端项目地址: https://github.com/haoxiaoyong1014/editor-ui 编辑器名称: tinymce 前端采用的 vue.js 至于Vue 中怎么集成 ...
  • 前端见微知著工具篇:Grunt实现自动化,百度富文本ueditor安装所需 转载说明(转自https://www.cnblogs.com/scy251147/p/4876489.html#top) 本篇文章为转载文章,来源为【前端福利】用grunt搭建自动化的web前端...
  • 最近一个消息插件中遇到一个特殊需求,就是一旦ueditor编辑器获取焦点以后,除非让编辑器失去焦点,否则window的键盘监听事件就失去作用了,在这种情况下如何才能使用ctrl+enter发送已经编辑好的内容呢?...
  • 因为做的后台系统做了切换路由功能,使每个路由都keep-alive,使用tinymce编辑器时总是第一次打开渲染不出内容而且不能编辑,都要刷新下才能正常显示和编辑,百度找了许多方法,试了一遍后找到了对我的项目有效的...
  • react富文本使用

    2018-03-20 18:49:00
    是否启用自动保存功能,默认启用 fullScreen bool true 是否启用全屏功能,默认启用 convertFormat string "html" 设置内容导入导出格式,支持html、markdown、raw三种格式,默认html ...
  • 在日常工作用,肯定有用到富文本编辑器的时候,富文本编辑器功能强大使用方便,我用的是百度富文本编辑器,首先需要下载好百度编辑器的demo, 然后创建ueditor.html文件,引入百度编辑器,然后在html文件内引入,然后再...
  • 在WEB API项目中使用KindEditor富文本编辑器
  • ylbtech-JavaScript-Tool-富文本:Simditor 1.返回顶部 1、 2、 2.返回顶部 1、 Simditor 是团队协作工具 Tower 使用的富文本编辑器。 相比传统的编辑器它的特点是: ...
  • 25、富文本编辑和ajax提交评论 1、django-ckeditor富文本表单 每个字段类型都有一个适当的默认Widget类 django-ckeditor提供widget from ckeditor.widgets import CKEditorWidget 要实现评论为富文本编辑的效果,...
  • layui 集成 editor.md 富文本编辑器

    万次阅读 热门讨论 2018-12-20 10:31:47
    #前言 lyaui是国产的,对后端程序员友好的前端UI框架,editor.md是国产的,功能非常全面的Markdown富文本编辑器
  • 目录我与富文本编辑器的恩怨情仇前言前戏:快速搭个富文本编辑器依赖npm jiǒ 本欢迎 Quill 登场身子热乎了,来撸起袖子干知己知彼开始心心念的事情首先将编辑器的字体改一下再给编辑器添加个分割线功能处理图片处理...
  • QLabel 功能很多, 可以用来显示图片 动画 富文本 1 效果 对于图片和动画, 先添加到资源文件再使用 右键 Resources -> 添加现有文件 使用资源时, 在Resources中选择使用的图片或动画, 右键点击复制资源...
  • 富文本编辑器踩坑

    2020-03-07 13:45:27
    开发富文本编辑器的一些经验 以下是我在开发一个本业务场景下的富文本编辑器的一些经验: 在开源富文本编辑器的基础上开发 知乎上有个问题,叫做为什么都说富文本编辑器是天坑?,里面提到的很多开发富文本编辑器会...
  • 初始化时设置添加事件:文本域失去焦点后自动保存。 //失去焦点后自动保存文本域内容 afterBlur : function ( ) { this . sync ( ) ; } 完整代码 前台 < % @page contentType = "text/...
  • 最近写项目中需要用到LayUI富文本编辑器...我们获取的内容是textarea中内容,富文本域中的内容和textarea中的内容不是自动同步的,所以我们需要在提交前把内容同步一下。 form表单提交: 首先定义文本域和提交按...
  • 1.富文本编辑器 1.1快速了解 借助富文本编辑器,网站的编辑人员能够像使用offfice一样编写出漂亮的、所见即所得的页面。此处以tinymce为例,其它富文本编辑器的使用也是类似的。 在虚拟环境中安装包。 pip...
  • 设置UEditor富文本编辑器宽度随页面大小自适应 解决方法: 1.打开/ueditor/ueditor.config.js 找到initialFrameWidth属性,默认值是1000.即是initialFrameWidth: 1000 把值更改为'100%' , 即是initialFrameWidth:...
  • 前言最近因业务需求在项目中嵌入了tinymce这个富文本编辑器,用于满足平台给用户编辑各类新闻内容什么的业务需求,前后也花了不少时间体验和对比了市面上各类开源编辑器。*案例demo版本:vue-tinymce-demo在线预览:...
  • 公司最近做一个项目,其中有一个模块是富文本编辑模块,之前没做个类似的功能模块,本来以为这个功能很常见应该会有已经造好的轮子,或许我只要找到轮子,研究下轮子,然后修改打磨轮子,这件事就八九不离十了。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,396
精华内容 2,558
关键字:

自动刷新富文本