I'm trying to watch videos onClick in a modal without having to visit the video pages themselves.
I'm using Vue.js and through a series of Ajax calls I am able to get most of the way there.
Codpen:
If you click "vs Suns" at top, you get a listing of all video posts. Then clicking any of the images, the modal ponent pops up and takes in the title of the post dynamically.
I want to run a video in there as well so I try to run this script tag:
< script class="_nbaVideoPlayerScout" data-team="warriors" data-videoId="/video/{{unique videoId from post ajax call}}" data-width="768" data-height="732" src=".js"></script>
When the modal pops up, I see the correct title of the post/image I clicked on, and I see the script tag exactly as it should be in the inspector, but the script tag never runs.
Is there some different way I should be injecting this script than this? (This is inside the axios response call)
let theVideoId = response.data.content[0].videoID
let s = document.createElement('script')
s.setAttribute('class', '_nbaVideoPlayerScout')
s.setAttribute('data-team', 'warriors')
s.setAttribute('data-videoId', '/video/' + theVideoId)
s.setAttribute('data-width', '768')
s.setAttribute('data-height', '732')
s.setAttribute('src', '.js')
document.getElementById('popupVideo').appendChild(s);
MODAL COMPONENT -- Fired on the click of one of the post thumbnails
const videoModal = Vueponent('VideoModal', {
props: {
id: {
type: String,
required: true
}
},
data: function () {
return {
post: [],
}
},
mounted() {
const singleApi = '.nba/warriors/api/1.1/json?textformat=html&nid='
axios.get(singleApi + this.id).then((response) => {
this.post = response.data.content[0]
console.log('THE RESPONSE', response)
let theVideoId = response.data.content[0].videoID
let s = document.createElement('script')
s.setAttribute('class', '_nbaVideoPlayerScout')
s.setAttribute('data-team', 'warriors')
s.setAttribute('data-videoId', '/video/' + theVideoId)
s.setAttribute('data-width', '768')
s.setAttribute('data-height', '732')
s.setAttribute('src', '.js')
document.getElementById('popupVideo').appendChild(s);
}).catch((error) => {
console.log(error)
})
},
methods: {
goBack: function () {
router.go(-1)
}
},
template:`<div>
<div id="video-popup">
<button class="close-video-popup" @click="goBack">close me</button>
<div class="video-popup-wrapper">
<div class="video-popup--title">{{post.title}}</div>
<div class="video-popup--video" id="popupVideo"></div>
<div class="video-popup--share"></div>
</div>
</div>
</div>`
})
I'm trying to watch videos onClick in a modal without having to visit the video pages themselves.
I'm using Vue.js and through a series of Ajax calls I am able to get most of the way there.
Codpen: https://codepen.io/nolaandy/pen/BrbBzO
If you click "vs Suns" at top, you get a listing of all video posts. Then clicking any of the images, the modal ponent pops up and takes in the title of the post dynamically.
I want to run a video in there as well so I try to run this script tag:
< script class="_nbaVideoPlayerScout" data-team="warriors" data-videoId="/video/{{unique videoId from post ajax call}}" data-width="768" data-height="732" src="https://www.nba./scout/team/cvp/videoPlayerScout.js"></script>
When the modal pops up, I see the correct title of the post/image I clicked on, and I see the script tag exactly as it should be in the inspector, but the script tag never runs.
Is there some different way I should be injecting this script than this? (This is inside the axios response call)
let theVideoId = response.data.content[0].videoID
let s = document.createElement('script')
s.setAttribute('class', '_nbaVideoPlayerScout')
s.setAttribute('data-team', 'warriors')
s.setAttribute('data-videoId', '/video/' + theVideoId)
s.setAttribute('data-width', '768')
s.setAttribute('data-height', '732')
s.setAttribute('src', 'https://www.nba./scout/team/cvp/videoPlayerScout.js')
document.getElementById('popupVideo').appendChild(s);
MODAL COMPONENT -- Fired on the click of one of the post thumbnails
const videoModal = Vue.ponent('VideoModal', {
props: {
id: {
type: String,
required: true
}
},
data: function () {
return {
post: [],
}
},
mounted() {
const singleApi = 'https://cors-anywhere.herokuapp./www.nba./warriors/api/1.1/json?textformat=html&nid='
axios.get(singleApi + this.id).then((response) => {
this.post = response.data.content[0]
console.log('THE RESPONSE', response)
let theVideoId = response.data.content[0].videoID
let s = document.createElement('script')
s.setAttribute('class', '_nbaVideoPlayerScout')
s.setAttribute('data-team', 'warriors')
s.setAttribute('data-videoId', '/video/' + theVideoId)
s.setAttribute('data-width', '768')
s.setAttribute('data-height', '732')
s.setAttribute('src', 'https://www.nba./scout/team/cvp/videoPlayerScout.js')
document.getElementById('popupVideo').appendChild(s);
}).catch((error) => {
console.log(error)
})
},
methods: {
goBack: function () {
router.go(-1)
}
},
template:`<div>
<div id="video-popup">
<button class="close-video-popup" @click="goBack">close me</button>
<div class="video-popup-wrapper">
<div class="video-popup--title">{{post.title}}</div>
<div class="video-popup--video" id="popupVideo"></div>
<div class="video-popup--share"></div>
</div>
</div>
</div>`
})
Share
Improve this question
asked Apr 10, 2018 at 19:08
4ndy4ndy
4588 silver badges27 bronze badges
6
- this answer might help you stackoverflow./a/8578840/1309377 – Andrew L Commented Apr 10, 2018 at 19:28
- I wish that worked but I get the same thing. Script added but nothing is run. – 4ndy Commented Apr 10, 2018 at 19:46
- It's crazy because if I add a script with an alert in it, I get the alert popup: var s = document.createElement('script') s.type = 'text/javascript' var code = 'alert("'+theVideoId+'");' try { s.appendChild(document.createTextNode(code)); document.getElementById('scriptMe').appendChild(s); } catch (e) { s.text = code; document.getElementById('scriptMe').appendChild(s); } – 4ndy Commented Apr 10, 2018 at 21:16
- are there any errors in the dev console? What do you expect to happen when you load this script? – Andrew L Commented Apr 10, 2018 at 21:22
- I'm trying to show a video. No errors at this time. If you add this script tag into a codepen you will see the video popup: <script class="_nbaVideoPlayerScout" data-team="warriors" data-videoId="/video/teams/warriors/2018/04/09/2041192/1523301309011-shorts-phx-2041192" data-width="768" data-height="732" src="nba./scout/team/cvp/videoPlayerScout.js">< / script> I can inject this exact script but I don't get the video. – 4ndy Commented Apr 10, 2018 at 21:33
1 Answer
Reset to default 6On a whim I made this change:
// document.getElementById('scriptMe').appendChild(s);
document.body.appendChild(s);
and boom, script runs and video loads.
Which is super interesting, because "why", right?
Edit: In addition, trying other script injection methods discussed here.
document.write method
document.write(s.outerHTML) // s is a script node
also works. In fact, you can embed that script node in a div
and it works as well.
createContextualFragment method
// var $container = document.getElementById('scriptMe'); // does not work
var $container = document.body
var range = document.createRange()
$container.appendChild(range.createContextualFragment(script_str))
works, where script_str
is an html string literal. This will work both as "<script>....</script>"
or "<div id="myDiv"><script>...</script></div>"
but all the methods I tested ultimately needed injection to be done in body
.
codepen