Плагин vue, который инкапсулирует iframe, изменяет стиль и скрывает полосу прокрутки.

Vue.js

Когда у меня будет время в последнее время, я найду время, чтобы медленно извлечь бизнес-компоненты компании, которые я сделал раньше, и превратить их в плагины.Это можно рассматривать как краткое изложение технических аспектов последних лет.

То, что я собираюсь написать сегодня, — это плагин iframe, инкапсулированный с помощью vue-jsx, который может изменять стиль в iframe, скрывать полосу прокрутки и обеспечивать безопасность страницы по умолчанию. Если вы не хотите его видеть и хотите использовать напрямую, перейдите в офис проекта.pikaz-iframe,

задний план

Поскольку компания просматривает некоторые статьи, необходимость в статье для отображения, первая мысль, конечно, iframe, хотя у него есть такие недостатки, но все же нужно сказать, быстрое и простое решение.

общие атрибуты iframe

параметр иллюстрировать
frameborder Показывать ли границу iframe
sandbox Включить дополнительные ограничения на контент в iframe
src URL-адрес вложенной страницы
srcdoc HTML-контент

Существует не так много часто используемых атрибутов iframe, и вышеприведенные используются примерно:

frameborder контролирует, отображает ли iframe границу, обычно устанавливается в 0, то есть не отображается, а дальше стиль границы пишется css;

Песочница управляет контролем разрешений на доступ к содержимому iframe. Если вам нужно только отобразить страницу, вы можете настроить ее на разрешение разрешающих сценариев того же происхождения. Первое имеет то же происхождение, а второе позволяет iframe включать сценарии. , так что отображаемая страница не может создать форму отправки, допускающую опасные операции, такие как всплывающие окна! , кроме того, настоятельно рекомендуется не использовать одновременно сценарии allow-scripts и allow-same-origin, когда встраиваемый документ имеет то же происхождение, что и главная страница. При совместном использовании встроенные документы могут кодировать удаление атрибута песочницы. Если у вас есть другие потребности, вы можете перейти кMDN-iframeПроверить;

Большинство людей знают src, передают URL-адрес и отображают веб-страницу;

srcdoc может передавать html-контент и отображать веб-страницы.На самом деле, в vue также есть инструкция v-html, которая может отображать html-контент, но недостатком является то, что она легко загрязняется глобальным стилем CSS, и требуется дополнительная инкапсуляция. , а контроль разрешений также должен быть инкапсулирован, так что это компромисс.При импорте веб-контента используйте фреймы.

оболочка плагина iframe

Поскольку в iframe слишком много атрибутов, мы не можем написать атрибуты один за другим в шаблоне, поэтому, естественно, мы должны использовать функцию рендеринга Vue для их записи.

ps: не спрашивайте меня, почему я использую vue.Конечно, я использую то, что представляет собой технологический стек компании.Вообще, я редко использую vue для написания jsx.Я пишу его только тогда, когда переключаюсь на реакцию, но я был удивлен, когда я написал это на этот раз JSX Vue может использовать инструкции, такие как v-model! удивительно!

Код включен!

.vue file:

export default {
  props: {
    setting:Object  
  },
  render () {
    return (
      <iframe {...{ attrs: this.attrs }}>
      </iframe>
    );
  },
  computed:{
    attrs(){

    }
  }
}

Обработка атрибутов iframe

Сначала используйте параметр настройки, чтобы получить все необходимые параметры, затем обработайте параметры, требуемые тегом iframe, в вычислении, а затем верните.

Значение по умолчанию для песочницы и границы кадра обрабатывается в атрибуте. По умолчанию граница отсутствует. При использовании URL-адреса установите для него значение «разрешить сценарии того же происхождения», а при использовании содержимого html установите значение «разрешить сценарии». для обеспечения безопасности.

attrs(){
  const attr = {}
  Object.keys(this.setting).forEach(key => {
      if (!(key === 'hideScrolling' || key === 'css')) {
          attr[key] = this.setting[key]
        }
        // 处理css样式
        if (key === 'srcdoc' && this.setting.css && this.setting.srcdoc) {
          // 查找head标签
          const pattern = "<head.*(?=>)(.|\n)*?</head>"
          const html = this.setting.srcdoc.match(pattern)[0]
          // 插入style
          const style = `<style>${this.setting.css}</style></head>`
          const newHtml = html.replace("</head>", style)
          const doc = this.setting.srcdoc.replace(html, newHtml)
          attr[key] = doc
        }
      })

      // 设置默认值
      if (!attr.sandbox || attr.sandbox !== '') {
        // 同源文档
        if (this.setting.srcdoc) {
          attr.sandbox = 'allow-scripts'
        } else {
          attr.sandbox = 'allow-same-origin allow-scripts'
        }
      }
      // 无边框
      if (!attr.frameborder) {
        attr.frameborder = 0
      }
      return attr
}

Srcdoc изменить содержимое стиля

Кроме того, поскольку продукту необходимо изменить полосу прокрутки документа, ему также нужна функция для изменения стиля:

Передайте параметр css в настройках, который является кодом стиля css, а затем все, что вам нужно сделать, это вставить стиль css во входящий html-контент.

Сначала найдите тег head

  const pattern = "<head.*(?=>)(.|\n)*?</head>"
  const html = this.setting.srcdoc.match(pattern)[0]

Затем добавьте стиль css в конец заголовка и назначьте его атрибуту srcdoc.

  const style = `<style>${this.setting.css}</style></head>`
  const newHtml = html.replace("</head>", style)
  const doc = this.setting.srcdoc.replace(html, newHtml)
  attr['srcdoc'] = doc

скрыть полосу прокрутки

Кроме того, некоторым страницам не нужны полосы прокрутки, поэтому им также нужна функция скрытия полос прокрутки:

Полоса прокрутки по умолчанию в Google Chrome имеет ширину 18 пикселей, поэтому вам нужно только установить ширину во внешнем контейнере и установить overflow-x: hidden; ширина внутреннего iframe на 18 пикселей больше, чем внешняя, а полоса прокрутки может Конечно, вам также необходимо учитывать Проблема совместимости заключается в том, что полосы прокрутки некоторых браузеров не обязательно имеют ширину 18 пикселей, поэтому они также должны получать значение ширины и устанавливать iframe больше, чем внешняя ширина.

render () {
    return (
      <div id="pikaz-iframe-container">
        <iframe {...{ attrs: this.attrs }} style={this.hideScrollBar}>
        </iframe>
      </div>
    );
  },
computed:{
  hideScrollBar () {
      if (this.setting.hideScrolling) {
        if (Object.prototype.toString.call(this.setting.hideScrolling) === "[object String]") {
          return { width: `calc(100% + ${this.setting.hideScrolling})` }
        } else {
          return { width: `calc(100% + 18px)` }
        }
      }
      return {}
    },
}

...
<style scoped>
#pikaz-iframe-container {
  width: 100%;
  height: 100%;
  overflow-x: hidden;
}
#pikaz-iframe-container::-webkit-scrollbar {
  display: none;
}
#pikazIframe {
  width: 100%;
  height: 100%;
}
</style>

iframe загружает полный обратный вызов

Вам нужно только добавить функцию обратного вызова к загруженной загрузке iframe, что относительно просто

render () {
    return (
      <div id="pikaz-iframe-container">
        <iframe {...{ attrs: this.attrs }} style={this.hideScrollBar} id="pikazIframe">
        </iframe>
      </div>
    );
},
mounted () {
    this.iframeOnload()
},
methods: {
    iframeOnload () {
      this.$nextTick(() => {
        const iframe = document.getElementById("pikazIframe");
        const that = this
        iframe.onload = function () {
          that.$emit("onload")
        }
      })
    }
},

ps: Друг в комментариях напомнил, что загрузка iframe будет срабатывать и в случае 404. Вернувшись назад, я попытался решить эту проблему.Оказалось, что при передаче url iframe крестится -domain не удалось получить домен iframe, и, естественно, не было возможности судить. Является ли это страницей 404? Если есть лучший способ, пожалуйста, оставьте сообщение в области комментариев.

адрес проекта

Talk is cheap. Show you the code.

Чтобы просмотреть полный код, перейдите наpikaz-iframe

Он был загружен в npm и при необходимости может использоваться напрямую.

наконец

Если у вас есть помощь вам, пожалуйста, нажмите.