王一之 发表于 2024-10-15 01:03:27

我想把这个js中的_doSyncDuration方法重写,怎么做

各位大佬,由于我写的脚本在视频播放完毕后,跳转网页时,总会不正常跳转,它会优先跳转到js脚本定义的下一个网址,我已经找到关键位置,问题出在 n.autoClickNext()。所以我想重写关键方法。已经找到了需要修改的方法是_doSyncDuration。以上关键字在下面的脚本中都找得到。但这种js脚本写法我第一次看到,还不太会。怎么重写??下面是js脚本全部内容。
```
define(["jquery", "underscore", "backbone", "dialogExtend", "text!tmpl/video/stop-e47b59c660.text", "pdfobject"], function(e, t, i, o, n, r) {
    var s = i.View.extend({
      el: ".video-wrapper",
      initialize: function() {
            var t = this.$("#video").children("div")
            , i = t.attr("data-lessonId")
            , o = this.GetQueryString("id");
            o && (i = o),
            e(".video-title").each(function(o) {
                var n = e(this).attr("data-lessonId");
                n == i && (e(".video-title").removeClass("on"),
                e(this).addClass("on"),
                t = e(this))
            }),
            this._findAllVideos();
            var n = t.data("type")
            , r = t.attr("data-id");
            if (1 == n) {
                var s = t.attr("data-fileid");
                console.log(t);
                var a = t.data("state")
                  , l = this.isFullscreen();
                return l && this.xgplayer.exitFullscreen(),
                void this.loadDocument(s, a)
            }
            if (r) {
                var d = 0;
                this.initPlayer(i, d, 0)
            }
      },
      events: {
            "click .video-title": "clickVideoHandler"
      },
      eachDomId: function(t) {
            return e(".video-title").each(function(i) {
                var o = e(this).attr("data-lessonId");
                return o == t ? (e(".video-title").removeClass("on"),
                e(this).addClass("on"),
                e(this)) : void 0
            }),
            {}
      },
      packVideoQuality: function(e) {
            var i = []
            , o = e.urls;
            return o && o.length > 0 ? (1 == e.videoType ? i.push({
                name: "流畅",
                url: o.url + "?token=" + e.token
            }) : t.each(o, function(t) {
                switch (t.quality) {
                case "FLUENT":
                  i.push({
                        name: "流畅",
                        url: t.url + "?token=" + e.token
                  });
                  break;
                case "SD":
                  i.push({
                        name: "标清",
                        url: t.url + "?token=" + e.token
                  });
                  break;
                case "HD":
                  i.push({
                        name: "高清",
                        url: t.url + "?token=" + e.token
                  });
                  break;
                case "FULL_HD":
                  i.push({
                        name: "超清",
                        url: t.url + "?token=" + e.token
                  })
                }
            }),
            i) : void 0
      },
      initPlayer: function(e, i, o) {
            var n = this
            , r = t.findWhere(window.initlessons, {
                id: e
            });
            if (r) {
                if ("2" != r.transState) {
                  var s = this.isFullscreen();
                  s && this.xgplayer.exitFullscreen(),
                  this.xgplayer && this.xgplayer.forceDestroy(),
                  setTimeout(function() {
                        return n.xgplayer = null,
                        n.$("#video-Player").html("<div style='width:100%;margin-top:30%;text-align:center;font-size:15px;color:#f99933'>视频正在转码中...</div>"),
                        !1
                  }, 200)
                }
                var a = this.packVideoQuality(r);
                this.playingVideo = r,
                this.playingVideo.idx = i;
                var l = this.xgplayer ? this.xgplayer.volume : .5
                  , d = r.urls ? r.urls.url + "?token=" + r.token : ""
                  , c = this.videos.length;
                if (i + 1 == c)
                  var u = ["keyboard"];
                else
                  var u = ["keyboard", "replay"];
                var h = {
                  id: "video-Player",
                  url: d,
                  width: "100%",
                  height: "100%",
                  volume: l,
                  autoplay: !0,
                  lastPlayTimeHideDelay: 15,
                  definitionActive: "click",
                  closeVideoClick: !1,
                  videoBackground: {
                        isCustom: 1 == this.playingVideo.videoType ? !0 : !1
                  },
                  poster: r.urls ? r.urls.imageUrl : "",
                  ignores: u,
                  countTime: {
                        interval: 60,
                        cb: function(e) {
                            var t = formatUtil.getCookie("u-token")
                              , i = formatUtil.getCookie("ufo-urn");
                            3 != window.p.source && t && i && n.countTimeBack(e)
                        }
                  },
                  trying2Watch: {
                        maxTime: 3 == window.p.source ? 180 : 0,
                        cb: function() {
                            n.courseTestListen()
                        }
                  },
                  onTimeUpdate: function() {}
                };
                this.$("#video-Player").css("overflow", "hidden"),
                0 != o && this.xgplayer ? this.xgplayer && this.xgplayer.switchVideo && this.xgplayer.switchVideo(h, function(e) {
                  n.xgplayer = e,
                  n.$("#video-Player").css("float", "left"),
                  a && a.length > 1 && n.xgplayer.emit("resourceReady", a),
                  n.registEventPlayer()
                }) : (this.$("#video-Player").html(""),
                this.xgplayer = grtPlayer(h),
                a && a.length > 1 && this.xgplayer.emit("resourceReady", a),
                this.registEventPlayer())
            }
      },
      registEventPlayer: function() {
            var e = this;
            this.xgplayer.once("play", function() {
                console.log("开始播放了====================3"),
                e.recordCourseHitNum()
            })
      },
      clickVideoHandler: function(t) {
            var i = e(t.currentTarget)
            , o = i.data("type")
            , n = i.attr("data-lessonId")
            , r = i.attr("data-parentId");
            "615780598560169984" == r && (window.location.href = "https://tv.cctv.com/2020/12/27/VIDAkfdoj8E8LsTWYaWd7Cnk201227.shtml");
            var s = i.attr("data-id");
            i.attr("data-videoType");
            if (!i.hasClass("on")) {
                if (this.$(".video-title.on").removeClass("on"),
                i.addClass("on"),
                1 == o) {
                  var a = i.attr("data-fileId")
                      , l = i.data("state")
                      , d = this.isFullscreen();
                  return d && this.xgplayer.exitFullscreen(),
                  this.loadDocument(a, l),
                  void (this.xgplayer = null)
                }
                var c = 0;
                this.videos.each(function(t, i) {
                  var o = e(this).attr("data-id");
                  s == o && (c = t)
                }),
                this.initPlayer(n, c, 1)
            }
      },
      countTimeBack: function(e) {
            var t = 0;
            e && (t = e.time ? e.time : 0),
            this._doSyncDuration.call(this, e.end, t)
      },
      _doSyncDuration: function(t, i) {
            var n = this
            , r = this.playingVideo.videoId
            , s = this.playingVideo.progressId;
            e.ajax({
                url: "/services/member/study/progress",
                dataType: "json",
                type: "post",
                _removeLoading: !0,
                headers: {
                  "u-platformId": window.platformInfo.id
                },
                data: {
                  courseId: window.courseId,
                  videoId: r,
                  itemId: window.p.itemId,
                  segId: window.courseId,
                  isFinish: t,
                  type: 2,
                  progressId: s,
                  playProgress: i,
                  courseType: 1
                },
                success: function(e) {
                  e.success && (n.updateProgressRender(e.data, r),
                  t && n.autoClickNext())
                },
                error: function(e) {
                  var t = e.responseJSON.resultCode;
                  401 == t && o.alert("您已退出登录,请重新登录。", function() {
                        var e = window.app_servers.uCenterServer.host + window.app_servers.uCenterServer.path
                        , t = window.detailInfo ? window.detailInfo.orgId : "";
                        return document.location.href = e + "/login?service=" + encodeURIComponent(document.location) + "&oid=" + t,
                        !1
                  }),
                  3003 == t && n.manageTagHandler()
                }
            })
      },
      GetQueryString: function(e) {
            var t = new RegExp("(^|&)" + e + "=([^&]*)(&|$)")
            , i = window.location.search.substr(1).match(t);
            return null != i ? unescape(i) : null
      },
      recordCourseHitNum: function() {
            e.ajax({
                url: "/services/course/public/course/course_hits/" + window.courseId,
                dataType: "json",
                _removeLoading: !0,
                type: "post",
                async: !0,
                data: {
                  visitType: 1,
                  schemaType: 2
                },
                success: function(e) {
                  e.success
                },
                error: function(e) {
                  if (e && e.responseJSON) {
                        var t = "请求失败";
                        t = e.responseJSON.message || t,
                        console.error(t)
                  }
                }
            })
      },
      loadDocument: function(e, t) {
            var i = this;
            this.pluginType = 1,
            this.trigger("Document_loaded"),
            this.xgplayer && this.xgplayer.forceDestroy(),
            setTimeout(function() {
                return i.xgplayer = null,
                2 != t ? void i.$("#video-Player").html("<div style='width:100%;margin-top:30%;text-align:center;font-size:18px;color:#f99933'>文档正在转码中...</div>") : void r.embed(window._ctx + "/tmpfile/pdffile?fid=" + e, "#video-Player", {
                  forcePDFJS: !0,
                  PDFJS_URL: window._ctx + "/lib/pdfjs/web/viewer.html"
                })
            }, 200)
      },
      isFullscreen: function() {
            return document.fullscreenElement || document.msFullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || !1
      },
      manageTagHandler: function() {
            var e = this.isFullscreen();
            e && this.xgplayer.exitFullscreen(),
            this.xgplayer && this.xgplayer.pause();
            var t = o.open({
                content: n,
                title: "",
                closeBtn: 0,
                btn: ["关闭页面", "刷新页面,继续学习"],
                area: ["550px", "350px"],
                yes: function() {
                  o.close(t),
                  -1 != navigator.userAgent.indexOf("Firefox") || -1 != navigator.userAgent.indexOf("Chrome") ? (window.location.href = "about:blank",
                  window.close()) : (window.opener = null,
                  window.open("", "_self"),
                  window.close())
                },
                cancel: function() {
                  location.reload()
                }
            })
      },
      updateProgressRender: function(e, t) {
            var i = this
            , o = parseFloat(e.progress);
            if (progressPercent = parseInt(100 * o),
            -1 != o) {
                var n = t;
                i.$(".catalog").find(".video-title").children(".four").text(progressPercent + "%")
            }
      },
      autoClickNext: function() {
            var e = this.videos.length
            , t = this.playingVideo.idx;
            if (0 != e && t != e - 1) {
                var i = this.videos.eq(t + 1);
                i.trigger("click")
            }
      },
      _findAllVideos: function() {
            var e = this.$(".video-title");
            this.videos = e
      },
      courseTestListen: function() {
            var t = this.isFullscreen();
            t && this.xgplayer.exitFullscreen(),
            this.xgplayer && (this.xgplayer.pause(),
            this.xgplayer.currentTime = 0);
            o.confirm("试听结束", {
                btn: []
            });
            e(".layui-layer-content").css("text-align", "center")
      },
      render: function() {
            this.vObj = this.$("#video").children("div").children("object"),
            this.objId = this.vObj.attr("id");
            this.$("#video-tabContent");
            return e(".g-content-wrapper").css({
                "min-height": e(window).height() - 49
            }),
            this.$("#video").css({
                height: e(window).height() - 110 + "px"
            }),
            e(".video-wrapper .video-tab").css({
                height: e(window).height() - 110 + "px"
            }),
            e(".video-tab-bd .catalog").css({
                height: e(window).height() - 160 + "px"
            }),
            e(".video-tab-bd .note").css({
                height: e(window).height() - 160 + "px"
            }),
            e(window).resize(function() {
                e(".video-wrapper .video").css({
                  height: e(window).height() - 70 + 20 + "px"
                }),
                e(".video-tab-bd .catalog").css({
                  height: e(window).height() - 121 + 20 + "px"
                }),
                e(".video-tab-bd .note").css({
                  height: e(window).height() - 121 + 20 + "px"
                }),
                e(".video-wrapper .video-tab").css({
                  height: e(window).height() - 50 + 20 + "px"
                })
            }),
            e(document).on("keyup", function() {
                return 32 == event.keyCode ? !1 : void 0
            }),
            this
      }
    });
    return new s
});

```

王一之 发表于 2024-10-15 01:03:45

看着有点像amd的模块导出方式
amd的默认模块名是文件名
可以尝试你通过油猴导出该文件直接篡改试试

李恒道 发表于 2024-10-15 01:04:33

看着有点像amd的模块导出方式
amd的默认模块名是文件名
可以尝试你通过油猴导出该文件直接篡改试试

李恒道 发表于 2024-10-15 01:04:44

还有一个思路,但是不一定能跑通
看amd里貌似引用了backbone的view extend
可以找到
```js
    Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
```
这部分的源码是
```js
    var extend = function(protoProps, staticProps) {
      var parent = this;
      var child;

      // The constructor function for the new subclass is either defined by you
      // (the "constructor" property in your `extend` definition), or defaulted
      // by us to simply call the parent constructor.
      if (protoProps && _.has(protoProps, 'constructor')) {
      child = protoProps.constructor;
      } else {
      child = function(){ return parent.apply(this, arguments); };
      }

      // Add static properties to the constructor function, if supplied.
      _.extend(child, parent, staticProps);

      // Set the prototype chain to inherit from `parent`, without calling
      // `parent`'s constructor function and add the prototype properties.
      child.prototype = _.create(parent.prototype, protoProps);
      child.prototype.constructor = child;

      // Set a convenience property in case the parent's prototype is needed
      // later.
      child.__super__ = parent.prototype;

      return child;
    };
```
而_在amd情况下引入的是
```js
    if (typeof define === 'function' && define.amd) {
      define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
      // Export global even in AMD case in case this script is loaded with
      // others that may still expect a global Backbone.
      root.Backbone = factory(root, exports, _, $);
      });

    // Next for Node.js or CommonJS. jQuery may not be needed as a module.
    }
```
调用的是underscore的库函数
而源码大概是
```js
    _.has = function(obj, key) {
      return hasOwnProperty.call(obj, key);
    };
```
所以可以得出一个大概的结论
针对view的extend的prop进行protoProps的call劫持应该可以拿到protoProps对象

repisal 发表于 2024-10-15 07:10:18

大佬,你写的内容我得消化消化,不会再请教

steven026 发表于 2024-10-15 08:29:43

最简单的方法重写`jQuery.prototype.trigger`阻止点击事件

```js
      autoClickNext: function() {
            var e = this.videos.length
            , t = this.playingVideo.idx;
            if (0 != e && t != e - 1) {
                var i = this.videos.eq(t + 1);
                i.trigger("click")
            }
      },
```

repisal 发表于 2024-10-15 10:05:14

我得先把对象拿到,重写方法的话,确实有很多办法。这个AMD模块我没见过,让我学习学习,试一下。

repisal 发表于 2024-10-15 23:44:54

各位大佬,我来反馈了。我把AMD相关的内容简单学习了下。3种方案实验结果:
导出篡改方式最直接暴力,能搞。
针对view的extend的prop进行protoProps的call劫持这个方案最高端,我没成功,extend没找到protoProps这个参数。
重写jQuery.prototype.trigger阻止点击事件这个方案最省事!

repisal 发表于 2024-10-15 23:46:26

话说这不是我提的问题么,怎么换成 王一之了。我在我的帖子找半天没找到

李恒道 发表于 2024-10-15 23:47:16

repisal 发表于 2024-10-15 23:44
各位大佬,我来反馈了。我把AMD相关的内容简单学习了下。3种方案实验结果:
导出篡改方式最直接暴力,能搞 ...
哥哥有兴趣可以开个帖子详细聊聊amd的导出导入劫持问题,这方面我犯懒还没写
{:4_98:}
哥哥写的还算详细的话可以进指南
页: [1] 2
查看完整版本: 我想把这个js中的_doSyncDuration方法重写,怎么做