vue中screenfull.js和手动控制元素全屏,解决esc和全屏图标返回图标不改变selfFullscreen的情况,代码拿过去直接用和参考

1 篇文章 0 订阅

使用方法

1、组件载入screenfull.js,参考下文代码
2、注册与挂载
3、手动书写操作api
注意:vuedraggable 自行搜索安装
整体项目参考git项目:git@github.com:zengbotao/jindu_learn.git

<template>
  <div id="app" style="padding: 10px">
    <!--使用draggable组件-->
    <div class="itxst">
      <div class="col" id="right">
        <div class="title">
          左侧盒子
          <div v-show="selfFullscreen">
            <span class="save" @click="onAllFix">
              <i class="el-icon-menu"></i>
              <span class="close-full-screen">退出全屏</span>
            </span>
          </div>
          <div v-show="!selfFullscreen">
            <span class="save" @click="onAllFix">
              <i class="el-icon-menu"></i>
              <span class="close-full-screen">全屏</span>
            </span>
          </div>
        </div>
        <draggable
          v-model="arr1"
          group="site"
          animation="300"
          dragClass="dragClass"
          @start="onStart"
          @end="onEnd"
        >
          <!-- <draggable
            v-model="arr1"
            group="site"
            animation="300"
            dragClass="dragClass"
            ghostClass="ghostClass"
            chosenClass="chosenClass"
            @start="onStart"
            @end="onEnd"
          > -->
          <transition-group
            style="
              display: flex;
              flex-flow: row wrap;
              min-width: 500px;
              width: 100%;
              background-color: pink;
            "
          >
            <div class="item" v-for="item in arr1" :key="item.id">
              {{ item.name }}
            </div>
          </transition-group>
        </draggable>
      </div>
      <!-- <div class="col">
          <div class="title">右侧盒子</div>
          <draggable
            v-model="arr2"
            group="site"
            animation="100"
            dragClass="dragClass2"
            ghostClass="ghostClass"
            chosenClass="chosenClass"
            @start="onStart"
            @end="onEnd"
          >
            <transition-group>
              <div class="item" v-for="item in arr2" :key="item.id">{{ item.name }}</div>
            </transition-group>
          </draggable>
        </div> -->
    </div>
  </div>
</template>

<script>
import draggable from "vuedraggable";
import screenfull from "../utils/screenfull";
export default {
  data() {
    return {
      drag: false,
      selfFullscreen: false,
      arr1: [
        { id: 1, name: "左侧盒子一" },
        { id: 2, name: "左侧盒子二" },
        { id: 3, name: "左侧盒子三" },
        { id: 4, name: "左侧盒子四" },
        { id: 5, name: "右侧盒子四" },
      ],
      //https://blog.csdn.net/agua001/article/details/122318236
      //使用 transition-group无法拖入一个空数组
      //style="display: flex;height: 100px"注意高度的适配
      //简易的拖拽看板
      arr2: [
        { id: 1, name: "右侧盒子一" },
        { id: 2, name: "右侧盒子二" },
        { id: 3, name: "右侧盒子三" },
        { id: 4, name: "右侧盒子四" },
      ],
    };
  },
  mounted() {
    //screenfull有个onchange事件,在这里监测全屏状态
    screenfull &&
      screenfull.isEnabled &&
      screenfull.onchange(() => {
        this.selfFullscreen = !this.selfFullscreen;
      });
  },
  methods: {
    onStart() {
      this.drag = true;
    },
    onEnd() {
      this.drag = false;
    },
    // 全屏
    onAllFix() {
      let main = document.querySelector("#right");
      if (this.selfFullscreen) {
        screenfull.exit(); //相当于下面注释的代码
        // if (document.exitFullscreen) {
        //   document.exitFullscreen()
        // } else if (document.mozCancelFullScreen) {
        //   document.mozCancelFullScreen()
        // } else if (document.webkitCancelFullScreen) {
        //   document.webkitCancelFullScreen()
        // } else if (document.msExitFullscreen) {
        //   document.msExitFullscreen()
        // }
      } else {
        screenfull.request(main); //相当于下面注释的代码
        // if (main.requestFullscreen) {
        //   main.requestFullscreen()
        // } else if (main.mozRequestFullScreen) {
        //   main.mozRequestFullScreen()
        // } else if (main.webkitRequestFullScreen) {
        //   main.webkitRequestFullScreen()
        // } else if (main.msRequestFullscreen) {
        //   main.msRequestFullscreen()
        // }
      }
    },
  },
  components: {
    draggable,
  },
};
</script>

<style lang="scss" scoped>
.ghostClass {
  background-color: blue !important;
}

.chosenClass {
  background-color: rgb(12, 88, 150) !important;
  color: white !important;
}

.dragClass {
  background-color: skyblue !important;
}
.dragClass2 {
  background-color: rgb(235, 135, 135) !important;
}
.itxst {
  margin: 10px;
}

.title {
  padding: 6px 12px;
}

.col {
  width: 100%;
  min-width: 600px;
  height: 600px;
  background-color: #fff;
  flex: 1;
  padding: 10px;
  border: solid 1px #eee;
  border-radius: 5px;
  float: left;
}

.col + .col {
  margin-left: 30px;
}
//表示选择相邻兄弟,叫做“相邻兄弟选择器”,该选择器能够匹配指定元素后面相邻的兄弟元素。
.item {
  padding: 6px 12px;
  margin: 0px 10px 0px 10px;
  border: solid 1px #eee;
  background-color: #f1f1f1;
}
// .col :nth-child(odd){
//   width: 45%;
//   height: 50px;
// }
// .col :nth-child(even){
//   width: 45%;
//   height: 50px;
// }
.item:hover {
  background-color: #fdfdfd;
  cursor: move;
}

.item {
  border-top: none;
  margin: 6px;
  min-width: 45%;
  flex: 1;
  min-height: 250px;
  max-height: 550px;
  height: 100%;
}
</style>

screenfull.js

/* eslint-disable promise/prefer-await-to-then */

const methodMap = [
	[
		'requestFullscreen',
		'exitFullscreen',
		'fullscreenElement',
		'fullscreenEnabled',
		'fullscreenchange',
		'fullscreenerror',
	],
	// New WebKit
	[
		'webkitRequestFullscreen',
		'webkitExitFullscreen',
		'webkitFullscreenElement',
		'webkitFullscreenEnabled',
		'webkitfullscreenchange',
		'webkitfullscreenerror',

	],
	// Old WebKit
	[
		'webkitRequestFullScreen',
		'webkitCancelFullScreen',
		'webkitCurrentFullScreenElement',
		'webkitCancelFullScreen',
		'webkitfullscreenchange',
		'webkitfullscreenerror',

	],
	[
		'mozRequestFullScreen',
		'mozCancelFullScreen',
		'mozFullScreenElement',
		'mozFullScreenEnabled',
		'mozfullscreenchange',
		'mozfullscreenerror',
	],
	[
		'msRequestFullscreen',
		'msExitFullscreen',
		'msFullscreenElement',
		'msFullscreenEnabled',
		'MSFullscreenChange',
		'MSFullscreenError',
	],
];

const nativeAPI = (() => {
	if (typeof document === 'undefined') {
		return false;
	}

	const unprefixedMethods = methodMap[0];
	const returnValue = {};

	for (const methodList of methodMap) {
		const exitFullscreenMethod = methodList?.[1];
		if (exitFullscreenMethod in document) {
			for (const [index, method] of methodList.entries()) {
				returnValue[unprefixedMethods[index]] = method;
			}

			return returnValue;
		}
	}

	return false;
})();

const eventNameMap = {
	change: nativeAPI.fullscreenchange,
	error: nativeAPI.fullscreenerror,
};

// eslint-disable-next-line import/no-mutable-exports
let screenfull = {
	// eslint-disable-next-line default-param-last
	request(element = document.documentElement, options) {
		return new Promise((resolve, reject) => {
			const onFullScreenEntered = () => {
				screenfull.off('change', onFullScreenEntered);
				resolve();
			};

			screenfull.on('change', onFullScreenEntered);

			const returnPromise = element[nativeAPI.requestFullscreen](options);

			if (returnPromise instanceof Promise) {
				returnPromise.then(onFullScreenEntered).catch(reject);
			}
		});
	},
	exit() {
		return new Promise((resolve, reject) => {
			if (!screenfull.isFullscreen) {
				resolve();
				return;
			}

			const onFullScreenExit = () => {
				screenfull.off('change', onFullScreenExit);
				resolve();
			};

			screenfull.on('change', onFullScreenExit);

			const returnPromise = document[nativeAPI.exitFullscreen]();

			if (returnPromise instanceof Promise) {
				returnPromise.then(onFullScreenExit).catch(reject);
			}
		});
	},
	toggle(element, options) {
		return screenfull.isFullscreen ? screenfull.exit() : screenfull.request(element, options);
	},
	onchange(callback) {
		screenfull.on('change', callback);
	},
	onerror(callback) {
		screenfull.on('error', callback);
	},
	on(event, callback) {
		const eventName = eventNameMap[event];
		if (eventName) {
			document.addEventListener(eventName, callback, false);
		}
	},
	off(event, callback) {
		const eventName = eventNameMap[event];
		if (eventName) {
			document.removeEventListener(eventName, callback, false);
		}
	},
	raw: nativeAPI,
};

Object.defineProperties(screenfull, {
	isFullscreen: {
		get: () => Boolean(document[nativeAPI.fullscreenElement]),
	},
	element: {
		enumerable: true,
		get: () => document[nativeAPI.fullscreenElement] ?? undefined,
	},
	isEnabled: {
		enumerable: true,
		// Coerce to boolean in case of old WebKit.
		get: () => Boolean(document[nativeAPI.fullscreenEnabled]),
	},
});

if (!nativeAPI) {
	screenfull = {isEnabled: false};
}

export default screenfull;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

waves0001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值